Dieses Dokument gibt es nur auf Englisch.

smard-cli — Usage

Task-oriented examples for the smard CLI, a client for the open SMARD chart-data API run by the Bundesnetzagentur — German electricity-market generation, consumption / residual load and wholesale prices. All output is JSON, so the examples pipe through jq where it helps.

Install

npm i -g @maschinenlesbar.org/smard-cli

The installed binary is smard. To run from a checkout instead of a global install, replace smard with node dist/src/cli/index.js (after npm run build).

Concepts in one line

A series is addressed by a (filter, region, resolution) triple. filter is a numeric series id (smard filters), region is a grid/bidding-zone code (smard regions), resolution is one of hour | quarterhour | day | week | month | year (smard resolutions). Generation/consumption values are in MWh, wholesale prices in EUR/MWh.


Use cases

1. Discover the available filters (series ids)

Why: you need the numeric filter id before you can request any data.

smard filters                       # full catalogue
smard filters --group consumption   # only one group

--group accepts generation | consumption | price | forecast. Output is an array of { id, label, group }. Grab just the ids for prices:

smard --compact filters --group price | jq '[.[].id]'
# [4169, 5078, 4996, ...]

2. List the valid regions and resolutions

Why: region and resolution are validated against fixed value sets; check them before scripting.

smard regions       # ["DE","AT","LU","DE-LU","DE-AT-LU","50Hertz","Amprion","TenneT","TransnetBW","APG","Creos"]
smard resolutions   # ["hour","quarterhour","day","week","month","year"]

DE-LU is the German-Luxembourg bidding zone; 50Hertz/Amprion/TenneT/ TransnetBW are the four German TSO control areas; APG/Creos are the Austrian/Luxembourg TSOs.

3. Get the newest data in one call

Why: latest reads the timestamp index and fetches the most recent window for you, so you don’t have to discover the timestamp first.

# Newest hourly day-ahead wholesale price for the DE-LU bidding zone (EUR/MWh)
smard latest 4169 DE-LU hour

Output is { meta_data, series }, where series is an array of [epochMillis, value] pairs, each timestamp the start of its hour. The window runs to the end of the week, so .series[-1] is usually [ts, null], and the last non-null point is the last published hour — often tomorrow 23:00, since the next day’s prices come out after the midday day-ahead auction. Show the price for the current hour:

smard --compact latest 4169 DE-LU hour \
  | jq -c '[.series[] | select(.[1] != null and .[0] <= now * 1000)][-1]'
# [1789502400000,199.46]

Since 1 October 2025 the day-ahead market sets quarter-hour prices: each hour value is the mean of the four quarterhour prices (smard latest 4169 DE-LU quarterhour).

4. Latest renewable generation (photovoltaics / wind)

Why: track the most recent realised feed-in by technology, in MWh.

smard latest 4068 DE hour    # Photovoltaik (PV)
smard latest 4067 DE hour    # Wind Onshore
smard latest 1225 DE hour    # Wind Offshore

Sum the latest PV window into a single total:

smard --compact latest 4068 DE hour | jq '[.series[][1] | select(. != null)] | add'

5. Total grid load vs. residual load

Why: compare total consumption (filter 410) against residual load (filter 4359, the load left after subtracting renewables) for the same window.

smard latest 410  DE week    # Stromverbrauch: Gesamt (total grid load)
smard latest 4359 DE week    # Stromverbrauch: Residuallast (residual load)

6. Fetch one explicit window (timestamps → series)

Why: pull a specific historical window rather than the newest one. Available windows roll over time, so read a current timestamp from timestamps instead of hard-coding one (stale timestamps return a 404).

smard timestamps 4169 DE-LU hour          # -> [ ..., <valid epoch-ms timestamps> ]

# Pick the last available window and fetch it
TS=$(smard --compact timestamps 4169 DE-LU hour | jq '.[-1]')
smard series 4169 DE-LU hour "$TS"

timestamps returns a plain number[] of epoch-millisecond window starts; series returns the same { meta_data, series } shape as latest.

7. Day-ahead price series for a neighbouring market

Why: each neighbouring bidding zone has its own price filter id; the region for these price series is DE-LU.

smard latest 254 DE-LU hour    # Großhandelspreis: Frankreich
smard latest 256 DE-LU hour    # Großhandelspreis: Niederlande
smard latest 259 DE-LU hour    # Großhandelspreis: Schweiz

Find any price filter id by label without leaving the shell:

smard --compact filters --group price | jq '.[] | select(.label | test("Frankreich"))'

8. Generation forecast for the next windows

Why: the forecast group holds the published prognoses (wind, PV, total).

smard latest 125 DE hour     # Prognose: Photovoltaik
smard latest 122 DE hour     # Prognose: Gesamt (total)

9. Quarter-hour table data

Why: the table command reads the separate table_data endpoint for a single window (3 positional args: filter region timestamp, no resolution).

smard table 410 DE <timestamp>

Note: table_data windows are a different timestamp set than the one timestamps returns, and the public API has no discovery endpoint for them, so a table call may 404 for a timestamp that is valid for series/latest.

10. Pretty vs. compact, and saving for later

Why: pipe machine-readable output into files or other tools.

smard --compact latest 410 DE day > load.json     # single-line JSON
smard --compact latest 4068 DE hour | jq '.series | length'   # count data points

Global options

These apply to every command and may be placed before or after it (before is recommended):

Option Description
-V, --version print the version
--base-url <url> API base URL (default https://www.smard.de)
--timeout <ms> time limit per request in ms, whole response included (0 = no timeout; default 30000; at most 2147483647)
--user-agent <ua> User-Agent header value
--max-retries <n> retries for transient 429/503 responses (default 2)
--max-response-bytes <n> cap response body size in bytes (0 = unlimited; default 100 MiB)
--compact print JSON on a single line instead of pretty-printed
-h, --help help for the program or a command (smard <command> --help)

Exit codes: 0 success, 4 on a 404 from the API, 1 for any other error (network, timeout, parse, non-404 status), non-zero for usage errors.

Quelle auf GitHub ansehen →