Summary
Extend vpplib/dwd_client.py (branch dev_dwd) to support the output formats expected by pvlib and windpowerlib, and to allow combining data from multiple DWD stations. This enables the vise-d dashboard to replace its external dwd_fetcher dependency with the vpplib-internal client.
Background
The vise-d dashboard currently uses a separate dwd_fetcher library as a dependency alongside vpplib. The goal is to consolidate all DWD data access into vpplib.dwd_client so that only one implementation exists. The dwd_fetcher features that are missing in the current DWDClient are documented below.
Acceptance Criteria
1. for_pvlib output mode
When get_observations() is called with for_pvlib=True, the returned DataFrame must have the following column names and units:
| Column |
Unit |
Source DWD column |
ghi |
W/m² |
GS_10, FG_LBERG, or ATMO_STRAHL |
dni |
W/m² |
derived or DS_10 |
dhi |
W/m² |
DS_10 or derived |
temp_air |
°C |
TT_10, TT_TU |
wind_speed |
m/s |
FF_10, FF |
pressure |
hPa |
PP_10, P0 |
Index must be a timezone-aware DatetimeIndex (Europe/Berlin).
2. for_windpowerlib output mode
When get_observations() is called with for_windpowerlib=True, the returned DataFrame must use a MultiIndex column structure as required by windpowerlib:
| Column tuple |
Unit |
('wind_speed', '10') |
m/s |
('temperature', '2') |
Kelvin |
('pressure', '0') |
Pa |
('roughness_length', '0') |
m (default: 0.15 for open terrain) |
Note: windpowerlib expects temperature in Kelvin and pressure in Pa.
3. allow_multi_station parameter
Add allow_multi_station: bool = False to get_observations(). When True, the client should fetch each requested parameter from the best available station independently (they may differ), then merge all parameter columns into a single DataFrame aligned on the datetime index. This is important for locations where no single station measures all required parameters (e.g. solar + wind at the same station).
4. Optional clearsky fallback
Add clearsky_fallback: bool = False parameter to get_observations(). When True and solar irradiance columns (ghi, dni, dhi) are missing from the fetched data, use pvlib to generate clearsky estimates for the given location. Add a warning entry to the returned metadata dict when the fallback is used. If pvlib is not installed, raise an ImportError with a clear message.
5. Unit conversion helpers
Add private helper methods:
_kelvin_to_celsius(series) — subtract 273.15
_celsius_to_kelvin(series) — add 273.15
_pa_to_hpa(series) — divide by 100
_hpa_to_pa(series) — multiply by 100
_kj_per_m2_to_w_per_m2(series, interval_minutes) — convert energy to power
Files to Modify
vpplib/dwd_client.py — extend DWDClient.get_observations() with new parameters
requirements.txt — verify pvlib is listed (already present)
Files to Create
test_dwd_client.py — see issue #[link to test issue] for test requirements
Implementation Notes
- The existing
get_observations() signature must remain backward compatible — all new parameters should be keyword arguments with sensible defaults.
- The
for_pvlib and for_windpowerlib flags are mutually exclusive; raise ValueError if both are True.
- Column renaming and unit conversion should happen after data quality filtering, not before.
- When
allow_multi_station=True, align all per-parameter DataFrames on the datetime index using pd.concat(..., axis=1) and handle gaps with pd.NA.
Related
- Branch:
dev_dwd
- Follow-up: Replace
dwd_fetcher in vise-d dashboard (separate issue in vise-d repo)
- Depends on: none
Summary
Extend
vpplib/dwd_client.py(branchdev_dwd) to support the output formats expected bypvlibandwindpowerlib, and to allow combining data from multiple DWD stations. This enables the vise-d dashboard to replace its externaldwd_fetcherdependency with the vpplib-internal client.Background
The vise-d dashboard currently uses a separate
dwd_fetcherlibrary as a dependency alongside vpplib. The goal is to consolidate all DWD data access intovpplib.dwd_clientso that only one implementation exists. Thedwd_fetcherfeatures that are missing in the currentDWDClientare documented below.Acceptance Criteria
1.
for_pvliboutput modeWhen
get_observations()is called withfor_pvlib=True, the returned DataFrame must have the following column names and units:ghiGS_10,FG_LBERG, orATMO_STRAHLdniDS_10dhiDS_10or derivedtemp_airTT_10,TT_TUwind_speedFF_10,FFpressurePP_10,P0Index must be a timezone-aware
DatetimeIndex(Europe/Berlin).2.
for_windpowerliboutput modeWhen
get_observations()is called withfor_windpowerlib=True, the returned DataFrame must use a MultiIndex column structure as required by windpowerlib:('wind_speed', '10')('temperature', '2')('pressure', '0')('roughness_length', '0')Note: windpowerlib expects temperature in Kelvin and pressure in Pa.
3.
allow_multi_stationparameterAdd
allow_multi_station: bool = Falsetoget_observations(). WhenTrue, the client should fetch each requested parameter from the best available station independently (they may differ), then merge all parameter columns into a single DataFrame aligned on the datetime index. This is important for locations where no single station measures all required parameters (e.g. solar + wind at the same station).4. Optional clearsky fallback
Add
clearsky_fallback: bool = Falseparameter toget_observations(). WhenTrueand solar irradiance columns (ghi,dni,dhi) are missing from the fetched data, usepvlibto generate clearsky estimates for the given location. Add a warning entry to the returned metadata dict when the fallback is used. Ifpvlibis not installed, raise anImportErrorwith a clear message.5. Unit conversion helpers
Add private helper methods:
_kelvin_to_celsius(series)— subtract 273.15_celsius_to_kelvin(series)— add 273.15_pa_to_hpa(series)— divide by 100_hpa_to_pa(series)— multiply by 100_kj_per_m2_to_w_per_m2(series, interval_minutes)— convert energy to powerFiles to Modify
vpplib/dwd_client.py— extendDWDClient.get_observations()with new parametersrequirements.txt— verifypvlibis listed (already present)Files to Create
test_dwd_client.py— see issue #[link to test issue] for test requirementsImplementation Notes
get_observations()signature must remain backward compatible — all new parameters should be keyword arguments with sensible defaults.for_pvlibandfor_windpowerlibflags are mutually exclusive; raiseValueErrorif both areTrue.allow_multi_station=True, align all per-parameter DataFrames on the datetime index usingpd.concat(..., axis=1)and handle gaps withpd.NA.Related
dev_dwddwd_fetcherin vise-d dashboard (separate issue in vise-d repo)