SMARD Connection

This module provides a read-only REST API connection to the SMARD (Strommarktdaten) API from Bundesnetzagentur (German Federal Network Agency).

You can access comprehensive German electricity market data including power generation by source, consumption patterns, market prices, and generation forecasts. The API provides historical data from 2015 onwards with multiple time resolutions.

Available Data Categories:

Power Generation by Source Access generation data for various energy sources including:

  • Solar (Photovoltaik)

  • Wind (Onshore and Offshore)

  • Nuclear

  • Coal (Lignite and Hard Coal)

  • Natural Gas

  • Hydro

  • Biomass

  • Pumped Storage

Power Consumption Track electricity consumption including:

  • Total Load

  • Residual Load

  • Pumped Storage Consumption

Market Prices View electricity market prices for:

  • Germany/Luxembourg

  • Neighboring Countries

  • Austria, Belgium, Norway, and others

Generation Forecasts Access forecasts for:

  • Solar Generation

  • Wind Generation (Onshore and Offshore)

  • Total Generation

Key Features:

  • No authentication required (public API)

  • Multiple time resolutions: 15min, hour, day, week, month, year

  • Geographic coverage: Germany, Austria, Luxembourg

  • Data available from 2015 onwards

  • Automatic caching for improved performance

For more information, visit the SMARD website. For detailed API specifications and endpoints, refer to the OpenAPI specification.


SmardConnection

class eta_nexus.connections.SmardConnection(url: str = 'https://smard.api.proxy.bund.dev/app', *, nodes: Nodes[SmardNode] | None = None)[source]

Connection to SMARD (Bundesnetzagentur Strommarktdaten) API.

Provides access to German electricity market data including power generation by source, consumption, market prices, and generation forecasts. No authentication required.

Parameters:

For detailed documentation including available filters, regions, time resolutions, and usage examples, see SMARD Connection.

logger: Logger = <Logger eta_nexus.connections.smard_connection (WARNING)>
property authentication: None

No authentication required for SMARD API.

read(nodes: SmardNode | Nodes[SmardNode] | None = None) pd.DataFrame[source]

Read the latest available values from SMARD.

Fetches the most recent data chunk for each node and returns the last available data point. Note that SMARD data has publication delay, so the “latest” value may be hours or days old depending on data type.

Parameters:

nodes – Single node or list/set of nodes to read values from.

Returns:

pandas.DataFrame containing the latest available values.

read_node(node: SmardNode, from_time: datetime, to_time: datetime, interval: timedelta, **kwargs: Any) pd.DataFrame[source]

Read data for a single SMARD node.

Due to SMARD API design, we need to: 1. Get available timestamps from index endpoint 2. Find appropriate starting timestamp for our time range 3. Request time series data from that timestamp

Parameters:
  • node – Node to read from

  • from_time – Start of the time series (timezone-aware).

  • to_time – End of the time series (timezone-aware).

  • interval – Time interval for resampling (currently unused, data returned at native resolution).

  • kwargs – Additional arguments (currently unused).

Returns:

DataFrame with node data

read_series(from_time: datetime, to_time: datetime, nodes: SmardNode | Nodes[SmardNode] | None = None, interval: TimeStep = 60, **kwargs: Any) pd.DataFrame[source]

Read time series data for multiple SMARD nodes.

url_parsed: ParseResult

URL of the server to connect to

usr: str | None

Username for login to server

pwd: str | None

Password for login to server

exc: BaseException | None

SmardNode

class eta_nexus.nodes.SmardNode(name: str, url: str, protocol: str, *args: Any, **kwargs: Any)[source]

Node for SMARD (Bundesnetzagentur Strommarktdaten) API.

Provides access to German electricity market data including: - Power generation by source - Power consumption - Market prices - Generation forecasts

Parameters:
  • filter – Data filter ID or name (e.g., ‘solar’, 1223, ‘total_load’)

  • region – Region code (e.g., ‘DE’, ‘50Hertz’, ‘AT’)

  • resolution – Time resolution (‘hour’, ‘quarterhour’, ‘day’, etc.)

filter: int
region: str
resolution: str
static get_filter_name(filter_id: int) str | None[source]

Get human-readable name for a filter ID.

Parameters:

filter_id – Filter ID

Returns:

Filter name or None if unknown

name: str

Name for the node.

url: str

URL of the connection.

url_parsed: ParseResult

Parse result object of the URL (in case more post-processing is required).

protocol: str

Protocol of the connection.

usr: str | None

Username for login to the connection (default: None).

pwd: str | None

Password for login to the connection (default: None).

interval: str | None

Interval

dtype: Callable | None

Data type of the node (for value conversion). Note that strings will be interpreted as utf-8 encoded. If you do not want this behaviour, use ‘bytes’.


Example Usage

Reading solar power generation data for Germany:


# Construct a node with the necessary information to request data from the SMARD API
# SMARD provides German electricity market data from Bundesnetzagentur
node = SmardNode(
    name="Solar_Generation_DE",
    url="https://smard.api.proxy.bund.dev/app",
    protocol="smard",
    filter=4068,  # Solar power generation (can also use string name "solar")
    region="DE",  # Germany
    resolution="hour",  # Available: 'quarterhour', 'hour', 'day', 'week', 'month', 'year'
)

# Start connection from one or multiple nodes
# The Connection class can be used for initializing the connection
connection = SmardConnection.from_node(node)

# Define time interval as datetime values
# SMARD has data from 2015 onwards
to_datetime = datetime(2025, 11, 11, 14, 19, 0, tzinfo=timezone.utc)
from_datetime = to_datetime - timedelta(days=2)

# read_series will request data from specified connection and time interval
# The DataFrame will have index with time delta of the specified interval in seconds
# If a node has a different interval than the requested interval, the data will be resampled.
if isinstance(connection, SmardConnection):
    result = connection.read_series(from_time=from_datetime, to_time=to_datetime, interval=3600)
else:
    raise TypeError("The connection must be a SmardConnection, to be able to call read_series.")

# Check out the SmardConnection documentation for more information about:
# - Available filters (solar, wind, nuclear, prices, etc.)
# - Regions (DE, AT, LU, and German control zones)
# - Time resolutions

Available Filters

Power Generation Filters:

  • lignite (1223): Lignite power generation

  • nuclear (1224): Nuclear power generation

  • wind_offshore (1225): Offshore wind generation

  • hydro (1226): Hydroelectric generation

  • other_conventional (1227): Other conventional sources

  • other_renewable (1228): Other renewable sources

  • biomass (4066): Biomass generation

  • wind_onshore (4067): Onshore wind generation

  • solar (4068): Solar/Photovoltaic generation

  • hard_coal (4069): Hard coal generation

  • pumped_storage_generation (4070): Pumped storage generation

  • natural_gas (4071): Natural gas generation

Power Consumption Filters:

  • total_load (410): Total electricity consumption

  • residual_load (4359): Residual load

  • pumped_storage_consumption (4387): Pumped storage consumption

Market Price Filters:

  • de_lu (4169): Germany/Luxembourg market price

  • neighbors_de_lu (5078): Neighboring countries to DE/LU

  • belgium (4996): Belgium market price

  • norway_2 (4997): Norway market price

  • austria (4170): Austria market price

Forecast Filters:

  • offshore_forecast (3791): Offshore wind forecast

  • onshore_forecast (123): Onshore wind forecast

  • solar_forecast (125): Solar generation forecast

  • other_forecast (715): Other sources forecast

  • wind_solar_forecast (5097): Combined wind and solar forecast

  • total_forecast (122): Total generation forecast


Supported Regions

  • DE: Germany

  • AT: Austria

  • LU: Luxembourg

  • DE-LU: Germany and Luxembourg combined

  • DE-AT-LU: Germany, Austria, and Luxembourg combined

  • 50Hertz: 50Hertz control area

  • Amprion: Amprion control area

  • TenneT: TenneT control area

  • TransnetBW: TransnetBW control area

  • APG: Austrian Power Grid

  • Creos: Creos Luxembourg


Time Resolutions

  • quarterhour: 15-minute intervals

  • hour: Hourly data

  • day: Daily aggregates

  • week: Weekly aggregates

  • month: Monthly aggregates

  • year: Yearly aggregates