Skip to content

feat(dwd_client): Add pvlib/windpowerlib output formatting and multi-station support #54

@Pyosch

Description

@Pyosch

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions