-
Notifications
You must be signed in to change notification settings - Fork 186
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DA Prices seems to have broken. #346
Comments
Hi, I'm not here to answer you about the problem, but to tell you that you have leaked your API Key in one of the images... |
Thanks, I changed token |
I have the same problem. It worked fine yesterday, but now i have the same problem as described by @PeteGilbert98. I think this means that Entso-E must have changed something in the XML, right? |
Dear all, thank you for the fast report. I see my dashboard also having the same behaviour now. I am currently on holiday without access to my computer but will be back soon. In the meantime a pull request with a fix is always welcome!
Get BlueMail for Android
…On 4 Oct 2024, 16:24, at 16:24, "Olaf Lüke" ***@***.***> wrote:
I have the same problem. It worked fine yesterday, but now i have the
same problem as described by @PeteGilbert98. I think this means that
Entso-E must have changed something in the XML, right?
--
Reply to this email directly or view it on GitHub:
#346 (comment)
You are receiving this because you were mentioned.
Message ID: ***@***.***>
|
As of today I am getting entsoe.exceptions.NoMatchingDataError, it worked fine for years so something has definitely changed. |
I have a suggested fix which looks like it works for the prices. But I haven't checked extensively. Here is how I have adjusted parse_prices (in parsers.py) (I had to add in this mapping because it wasn't behaving as expected without): `def parse_prices(xml_text):
Here is how I changed _parse_timeseries_generic ( in series_parsers.py):
Again, very untested. But looks promising. if the first value it queries, or the last value it queries are missing, the timeseries returned will be shorter than expected.** I haven't tested this on any of the other functionality at all!!! |
Please put this in a proper pull request and I'll look at it after my holiday thanks.
Get BlueMail for Android
…On 4 Oct 2024, 17:02, at 17:02, PeteGilbert98 ***@***.***> wrote:
I have a suggested fix which looks like it works for the prices. But I
haven't checked extensively.
Here is how I have adjusted parse_prices (in parsers.py) (I had to add
in this mapping because it wasn't behaving as expected without):
`def parse_prices(xml_text):
"""
Parameters
----------
xml_text : str
Returns
-------
pd.Series
"""
time_mapping = {
'15min': '15min',
'30min': '30min',
'60min': '60min',
'15T': '15min',
'30T': '30min',
'1H': '60min',
'1h': '60min',
'h': '60min',
'0.25H': '15min',
'0.5H': '30min',
}
series = {
}
for soup in _extract_timeseries(xml_text):
soup_series = _parse_timeseries_generic(soup, 'price.amount')
series[time_mapping[soup_series.index.freqstr]] = soup_series
return series`
Here is how I changed _parse_timeseries_generic ( in
series_parsers.py):
`def _parse_timeseries_generic(soup, label='quantity', to_float=True):
# Create a list to store all time series data
all_data = []
# Iterate over each period
for period in soup.find_all("period"):
# Extract start time, end time, and resolution for each period
start_time_str = period.find("start").text
resolution_str = period.find("resolution").text # PT6H, PT30M, etc.
start_time = pd.to_datetime(start_time_str)
# Convert ISO 8601 duration to a pandas Timedelta
resolution_timedelta = pd.to_timedelta(resolution_str)
# Loop over each point and extract position and price
for point in period.find_all("point"):
position = int(point.find("position").text)
value = point.find(label).text
if to_float:
value = float(value)
# Calculate the timestamp for this point based on the position and
resolution
timestamp = start_time + resolution_timedelta * (position - 1)
# Append the data
all_data.append([timestamp, value])
# Create a DataFrame from the combined data
df_combined = pd.DataFrame(all_data, columns=['Timestamp', label])
# Reindex the DataFrame to include the complete range
df_combined.set_index('Timestamp', inplace=True)
if soup.find('curvetype').text == 'A03':
# with A03 its possible that positions are missing, this is when values
are repeated
# see docs:
https://eepublicdownloads.entsoe.eu/clean-documents/EDI/Library/cim_based/Introduction_of_different_Timeseries_possibilities__curvetypes__with_ENTSO-E_electronic_document_v1.4.pdf
# so lets do reindex on a continious range which creates gaps if
positions are missing
# then forward fill, so repeat last valid value, to fill the gaps
# Create a complete date range for the specified periods using the
maximum resolution
complete_range = pd.date_range(start=df_combined.index.min(),
end=df_combined.index.max(),
freq=resolution_timedelta)
df_combined = df_combined.reindex(complete_range)
# Forward fill missing values
df_combined[label] = df_combined[label].ffill()
return df_combined[label]`
Again, very untested. But looks promising.
**Potential errors:
if the first value it queries, or the last value it queries are
missing, the timeseries returned will be shorter than expected.**
I haven't tested this on any of the other functionality at all!!!
--
Reply to this email directly or view it on GitHub:
#346 (comment)
You are receiving this because you were mentioned.
Message ID: ***@***.***>
|
@fboerman will do this eve. thanks |
for anyone looking for a quick fix: https://github.com/GeneralCP/entsoe2 as far as I can see there was a duplicate price today on the 4th for The Netherlands (22 and 23 rd position the same price). Apparantly the API then only gives positions 22 and skips 23. Not sure if this 'feature' is new or this is just the first time we have the exact same price 2 hours in a row. |
day ahead prices are also broken; all of the prices are the same. |
Day ahead prices seems to be broken. Does this change in Entsoe platform https://transparency.entsoe.eu/news/widget?id=66f5203d792e84032cbb9b71 have something to do with this? |
Yes, this is exactly the problem. The day ahead prices use "variable sized blocks" now: while entsoe-py expects every position to be present. |
There is another change I have noticed. If I request prices for today and for tomorrow (belgium) the prices for today using the 60min resolution as usual. But the prices of tomorrow are using the 15min resolution. For other countries the response is still using the 60min resolution. I am confused. So they make braking changes to a public api on a friday and only announce it 5 days before it happens... |
I made a parser for the new data type. Only tested with day a head prices so be carefully. Response all TimeSeries are combined to one pandas.Series with possibly (not likely) none equal time steps. Fell free to use this code you find this code usefully.
|
The above fix by @JaniKallankari works for day ahead prices in Finland. Here is a small guide to include it as a a hotfix to entsoe-py if others need it as well: Edit entsoe/parsers.py in Python's site-packages and add following:
And then change the entsoe/entsoe.py to use this new parser. First import the new parser function in line 14:
And then change the query_day_ahead_prices function defined in line 1202 to actually use it:
|
@JaniKallankari @miikasda thank you for your suggestions. as a tip, its usually much more readable if you enter such proposals as a pull request instead of a copy in an issue. I am using your code as hint for the fix I am currently writing for this issue. Many thanks to all in this thread for their suggestions! |
Regarding the suggestion above: resolution = resolution_map[period.find('resolution').text]
for point in period.findall('Point'):
position = float(point.find('position').text)-1
time_stamps.append(start_time+position*resolution)
if to_float:
values.append(float(point.find(value_key).text))
else:
values.append(point.find(value_key).text) This only works if the xml only contains one resolution, which is generally not the case. E.g. for DE_LU it usually contains 60min and 15min data. This would need to return a dict with the resolutions with one series per resolution to work with all regions. |
many thanks to all for the discussions, I have released a new version, 0.6.9, which fixes this issue. If you still encounter issues on this version please open a new issue! |
oh and @Roeland54 this is probably a mistake on Elia side I believe. I have send them an informal nudge hopefully they will fix it soon, I cant fix that in the package |
Hi @fboerman ,
I've noticed that as of today, the function getting the da_prices from entsoe seems to have broken. My assumption is that the format sent from the entsoe api must have changed.
As you can see, all prices now seem to be the same.
Here's what I think might be causing the issue:
On line 36, I would have expected the _extract_timeseries generator to produce multiple soup objects for the different days that I have queried. Instead only one object is returned.
This means, on line 88, the keys in the dictionary (on line 83) are overwritten, as the keys are non unique per day.
on line 92, the datetime index appears to be correct, covering the whole timespan of the (buffered) query.
When the (seemingly correct) index is combined with the data. Things start to break.
The text was updated successfully, but these errors were encountered: