In [1]:
Copied!
from fewspy import Api
api = Api(
url=r"https://www.hydrobase.nl/fews/nzv/FewsWebServices/rest/fewspiservice/v1/",
ssl_verify=False,
)
from fewspy import Api
api = Api(
url=r"https://www.hydrobase.nl/fews/nzv/FewsWebServices/rest/fewspiservice/v1/",
ssl_verify=False,
)
First we request the filters of our FEWS-API. It will return a dictionary in the same structure as the FEWS-API JSON response
In [2]:
Copied!
api.get_filters()
api.get_filters()
Out[2]:
[{'id': 'webservices',
'name': 'WebServices',
'child': [{'id': 'WDB',
'name': 'WAM Dashboard',
'child': [{'id': 'WDB_OW',
'name': 'Oppervlaktewater',
'child': [{'id': 'WDB_OW_KGM', 'name': 'Gemaal'},
{'id': 'WDB_OW_KST', 'name': 'Stuw'},
{'id': 'WDB_OW_INL', 'name': 'Inlaat'},
{'id': 'WDB_OW_KSL', 'name': 'Sluis'},
{'id': 'WDB_OW_MPN', 'name': 'Meetpunt (hydrologisch)'}]},
{'id': 'WDB_GW',
'name': 'Grondwater',
'child': [{'id': 'WDB_GW_GMW', 'name': 'Peilbuis'}]},
{'id': 'WDB_FC',
'name': 'Fysisch-Chemisch',
'child': [{'id': 'WDB_FC_PARA_ALGEMEEN', 'name': 'Algemene stoffen'},
{'id': 'WDB_FC_PARA_BASISFC',
'name': 'Basis fysisch-chemische stoffen'},
{'id': 'WDB_FC_MMN_KRW_TOESTAND',
'name': 'KRW toestandsbepaling meetpunten'},
{'id': 'WDB_FC_PARA_KRW_PRIORITAIR',
'name': 'KRW prioritaire stoffen (2013)'},
{'id': 'WDB_FC_PARA_SPECIFIEK',
'name': 'Specifiek verontreinigende stoffen'},
{'id': 'WDB_FC_MMN_GBM_TOTAAL',
'name': 'Gewasbeschermingsmiddelen meetpunten'},
{'id': 'WDB_FC_MPN_MMN_ZWEMWATER', 'name': 'Zwemwater meetpunten'},
{'id': 'WDB_FC_MPN_PARA_ALL',
'name': 'Alle fysisch-chemische meetpunten en parameters'}]},
{'id': 'WDB_ML',
'name': 'Meteorologie',
'child': [{'id': 'WDB_ML_KNMI_AWS',
'name': 'KNMI - Automatische weerstations (AWS)'},
{'id': 'WDB_ML_KNMI_IRIS',
'name': 'KNMI - Vrijwillige neerslagmeters (IRIS)'}]}]}]}]
Now we'll request the locations of an existing filter. In this example for filter_id WDB_OW_KGM (pumps/gemalen). The response JSON is parsed to a GeoPandas GeoDataFrame we can explore.
In [3]:
Copied!
locations = api.get_locations(filter_id="WDB_OW_KGM")
locations.explore()
locations = api.get_locations(filter_id="WDB_OW_KGM")
locations.explore()
Out[3]:
Make this Notebook Trusted to load map: File -> Trust Notebook
Let's see what we have for a known location id.
In [4]:
Copied!
locations.loc["NL34.HL.KGM311.HWZ1"]
locations.loc["NL34.HL.KGM311.HWZ1"]
Out[4]:
short_name KGM311 - HWZ1 (BE) lat 53.172517660606175 lon 6.579783481401717 x 234743.0 y 576863.0 z 0.0 parent_location_id NL34.HL.KGM311 geometry POINT (234743 576863) Name: NL34.HL.KGM311.HWZ1, dtype: object
Let's see what time-series are available for this location, using the FEWS API get time series. Dirty trick is to set end_time equal to start_time as the FEWS-API will give faster response. We set only headers to omit the transfer of actual time series data.
In [5]:
Copied!
from datetime import datetime
time_series_headers = api.get_time_series(
filter_id="WDB_OW_KGM",
location_ids=["NL34.HL.KGM156.KWK"],
start_time=datetime(2023,1,1),
end_time=datetime(2023,1,1),
only_headers=True)
print(f"We have {len(time_series_headers)} time series\n")
print("If we print the header of the first time series pretty we get:\n")
time_series_headers.time_series[0].header.__dict__
from datetime import datetime
time_series_headers = api.get_time_series(
filter_id="WDB_OW_KGM",
location_ids=["NL34.HL.KGM156.KWK"],
start_time=datetime(2023,1,1),
end_time=datetime(2023,1,1),
only_headers=True)
print(f"We have {len(time_series_headers)} time series\n")
print("If we print the header of the first time series pretty we get:\n")
time_series_headers.time_series[0].header.__dict__
We have 1 time series If we print the header of the first time series pretty we get:
Out[5]:
{'type': 'instantaneous',
'module_instance_id': 'Productie',
'location_id': 'NL34.HL.KGM156.KWK',
'parameter_id': 'Q [m3/s] [NVT] [OW]',
'time_step': {'unit': 'nonequidistant'},
'start_date': datetime.datetime(2023, 1, 1, 0, 0),
'end_date': datetime.datetime(2023, 1, 1, 0, 0),
'miss_val': -999.0,
'lat': 53.3514399934006,
'lon': 6.449843832251746,
'x': 225761.0,
'y': 596638.0,
'units': 'm3/s',
'station_name': 'KGM156 - KWK',
'z': 0.0,
'qualifier_id': ['productie']}
Now we have all relevant input for requesting the full time series. We request the full series again and now plot the events.
Notes:
- TimeSeriesSets in FEWSPY object follow the structure of a FEWS PI-JSON as found in the FEWS API get timeseries documentation
- The key-words are all
snake_case(e.g. location_ids), following Python-conventions whereas FEWS-API conforms tocamelCasing(locationIds in the same example). But that is all just style and convention, it all means the same!
In [6]:
Copied!
time_series_set = api.get_time_series(
filter_id="WDB_OW",
location_ids=["NL34.HL.KGM156.KWK"],
parameter_ids=["Q [m3/s] [NVT] [OW]"],
qualifier_ids=["productie"],
start_time=datetime(2022,9,1),
end_time=datetime(2023,1,1))
time_series = time_series_set.time_series[0]
time_series.events.value.plot(
ylabel=time_series.header.parameter_id,
title=time_series.header.location_id,
grid=True)
time_series_set = api.get_time_series(
filter_id="WDB_OW",
location_ids=["NL34.HL.KGM156.KWK"],
parameter_ids=["Q [m3/s] [NVT] [OW]"],
qualifier_ids=["productie"],
start_time=datetime(2022,9,1),
end_time=datetime(2023,1,1))
time_series = time_series_set.time_series[0]
time_series.events.value.plot(
ylabel=time_series.header.parameter_id,
title=time_series.header.location_id,
grid=True)
Out[6]:
<AxesSubplot: title={'center': 'NL34.HL.KGM156.KWK'}, xlabel='datetime', ylabel='Q [m3/s] [NVT] [OW]'>