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:
url – Base URL (default: https://smard.api.proxy.bund.dev/app)
nodes – Nodes to select in connection
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
- 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.
- 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 generationnuclear(1224): Nuclear power generationwind_offshore(1225): Offshore wind generationhydro(1226): Hydroelectric generationother_conventional(1227): Other conventional sourcesother_renewable(1228): Other renewable sourcesbiomass(4066): Biomass generationwind_onshore(4067): Onshore wind generationsolar(4068): Solar/Photovoltaic generationhard_coal(4069): Hard coal generationpumped_storage_generation(4070): Pumped storage generationnatural_gas(4071): Natural gas generation
Power Consumption Filters:
total_load(410): Total electricity consumptionresidual_load(4359): Residual loadpumped_storage_consumption(4387): Pumped storage consumption
Market Price Filters:
de_lu(4169): Germany/Luxembourg market priceneighbors_de_lu(5078): Neighboring countries to DE/LUbelgium(4996): Belgium market pricenorway_2(4997): Norway market priceaustria(4170): Austria market price
Forecast Filters:
offshore_forecast(3791): Offshore wind forecastonshore_forecast(123): Onshore wind forecastsolar_forecast(125): Solar generation forecastother_forecast(715): Other sources forecastwind_solar_forecast(5097): Combined wind and solar forecasttotal_forecast(122): Total generation forecast
Supported Regions
DE: GermanyAT: AustriaLU: LuxembourgDE-LU: Germany and Luxembourg combinedDE-AT-LU: Germany, Austria, and Luxembourg combined50Hertz: 50Hertz control areaAmprion: Amprion control areaTenneT: TenneT control areaTransnetBW: TransnetBW control areaAPG: Austrian Power GridCreos: Creos Luxembourg
Time Resolutions
quarterhour: 15-minute intervalshour: Hourly dataday: Daily aggregatesweek: Weekly aggregatesmonth: Monthly aggregatesyear: Yearly aggregates