# Prognosen

Die Prognose liefert die erwartete PV-Leistung für einen Standort in 15-Minuten-Intervallen.
Sie fragen sie über die `site_id` ab; Standort, Strings und Konfiguration kommen aus dem
gespeicherten Standort.

```bash
GET /v2/forecast/{site_id}
```

Zeitstempel sind standardmäßig in der **lokalen Zeitzone** des Standorts (siehe `timezone` in der
Antwort). Mit `?timezone=utc` erhalten Sie stattdessen UTC-Zeitstempel mit `Z` am Ende.

:::tip
Die vollständige Parameter- und Feldliste steht in der [API-Referenz](/api). Diese Seite erklärt
die Konzepte.
:::

## Parameter

| Parameter       | Bedeutung                                                                                                       |
|-----------------|-----------------------------------------------------------------------------------------------------------------|
| `forecast_days` | Prognosehorizont in Tagen. Ohne Angabe das Plan-Maximum. Hartes Limit 7, zusätzlich auf das Plan-Limit gekappt. |
| `past_days`     | Vergangene Tage vor heute (archivierte Prognose). Standard 0. Hartes Limit 30, auf das Plan-Limit gekappt.      |
| `include`       | Welche Feldgruppen zurückkommen (wiederholbar). Standard `default`.                                             |
| `timezone`      | Zeitzone der Zeitstempel: `local` (Standard) oder `utc`. `utc` liefert UTC-Zeitstempel mit `Z` am Ende.         |

:::note
`past_days` liefert **archivierte Prognosedaten**, nicht echte Messwerte. Für tatsächliche
vergangene Erträge nutzen Sie die [Historischen Daten](/de/v2/api/historical).
:::

## `include`-Gruppen

`include` ist wiederholbar und wählt **Feldgruppen** — nicht einzelne Spalten:

```bash
GET /v2/forecast/{site_id}?include=weather&include=irradiance
```

| Gruppe        | Felder                                                                                                  |
|---------------|---------------------------------------------------------------------------------------------------------|
| `default`     | `pv_power` (PV-Leistung in W).                                                                          |
| `weather`     | `temp`, `weather_code`, `wind_speed`, `relative_humidity`, `precipitation_mm`, `snow_water_equivalent`. |
| `irradiance`  | `ghi`, `dhi`, `bni` (horizontale Einstrahlung).                                                         |
| `clearsky`    | `pv_power_clearsky` (Leistung bei wolkenlosem Himmel).                                                  |
| `strings`     | Fügt den separaten `strings`-Block hinzu (siehe unten). `values` bleibt unverändert.                    |
| `variability` | Fügt das Min/Max-Band hinzu (siehe unten). **Kostenpflichtig**, nie Teil von `all`.                     |
| `all`         | Alle Feldgruppen **und** den `strings`-Block (aber **nicht** `variability`).                            |

:::note
`default` wird **nicht** automatisch ergänzt. Fragen Sie nur `weather` an, erhalten Sie
Wetterdaten ohne `pv_power`. Das Feld `included` in der Antwort spiegelt die aufgelöste Auswahl.
:::

## Antwortstruktur

```json title="Antwort (gekürzt)"
{
  "site_id": "site_rv8wm5…",
  "timezone": "Europe/Berlin",
  "computed_at": "2026-06-09T08:00:00",
  "included": [
    "default"
  ],
  "daily": [
    {
      "date": "2026-06-09",
      "pv_energy_kwh": 42.7,
      "temp_min": 11.0,
      "temp_max": 24.3
    }
  ],
  "values": [
    {
      "timestamp": "2026-06-09T12:00:00",
      "pv_power": 8200.0
    }
  ]
}
```

- **`daily`** — Tagesaggregate (Energie in kWh, Min/Max-Temperatur, dominanter Wettercode).
- **`values`** — Zeitreihe je 15 Minuten. `pv_power` ist die **Summe über alle Strings**.

## Der `strings`-Block

Mit `include=strings` (oder `all`) kommt ein separates Top-Level-Array `strings` im
**Long-/Tidy-Format** hinzu — eine Zeile pro Zeitschritt und String:

```json
"strings": [
{"timestamp": "2026-06-09T12:00:00", "string_index": 0, "string_id": "str_9f3a1c08", "pv_power": 5100.0, "gti": 820.0, "gti_shaded": 815.0},
{"timestamp": "2026-06-09T12:00:00", "string_index": 1, "string_id": "str_4b7e2d10", "pv_power": 3100.0, "gti": 760.0, "gti_shaded": 752.0}
]
```

- **`string_index`** verweist positionsbasiert auf `site.strings[i]` — gleiche Reihenfolge wie in
  `GET /v2/sites/{site_id}`. Immer vorhanden.
- **`string_id`** ist die stabile ID des Strings — der Verknüpfungsschlüssel zu seinen Messwerten.
  Bei gespeicherten Sites vorhanden; beim Inline-Endpunkt nur, wenn Sie am String eine `id`
  mitgegeben haben.
- Die **geneigte Einstrahlung** (`gti`, `gti_shaded`) liegt hier, nicht in `values`, weil sie von
  der String-Ausrichtung abhängt.
- Jeder String liefert in **jedem** Zeitschritt eine Zeile (nachts 0.0), daher keine Lücken.
- `values.pv_power` ist die Summe der String-Leistungen.

In einem DataFrame lässt sich der Block direkt laden und auf `string_index` pivotieren:

```python
import pandas as pd

df = pd.DataFrame(response["strings"])
wide = df.pivot(index="timestamp", columns="string_index", values="pv_power")
```

## Variabilitätsband (`include=variability`)

Das Band liefert eine Unter-/Obergrenze der PV-Leistung, sofern in Ihrem Plan
verfügbar. Eine Anfrage mit `include=variability` auf einem Plan ohne diese Funktion gibt **403** zurück.

- Felder: `pv_power_min` / `pv_power_max` in jeder `values`- und `strings`-Zeile sowie
  `pv_energy_kwh_min` / `pv_energy_kwh_max` in `daily`.
- **Horizont:** deckt etwa die **nächsten 48 h** ab. Außerhalb (und für `past_days`)
  gilt `min == max == pv_power` (flaches Band). Nicht abgedeckte Standorte erhalten ebenfalls
  ein flaches Band — keinen Fehler.
- `variability` wird **nie** von `all` mit eingeschlossen, sondern nur auf expliziten Wunsch.

## Caching & `computed_at`

Prognosen werden **nicht** bei jeder Anfrage neu berechnet, sondern nur so oft, wie Ihre Plan es zulässt.
Wiederholte Anfragen im selben Slot liefern dasselbe zwischengespeicherte Ergebnis; `computed_at` zeigt den
Berechnungszeitpunkt.

Der Cache wird automatisch ungültig, wenn sich der Standort ändert (Koordinaten, Strings,
Config) oder der Plan wechselt.

## Limits & Fehler

| Limit / Fehler                | Verhalten                                                                                             |
|-------------------------------|-------------------------------------------------------------------------------------------------------|
| Forecast-Zugrirff             | Ohne Forecast-Zugang im Plan → **403**.                                                               |
| Monatliche Anfragen           | Monatliches Anfragelimit (pro Nutzer & Endpunkt), Reset am Monatsersten → **429** bei Überschreitung. |
| `forecast_days` / `past_days` | Werte werden auf das Plan-Limit gekappt.                                                              |
| Standort nicht gefunden       | **404**.                                                                                              |

:::tip
Ihre konkreten Limits finden Sie auf der Seite über [Nutzung & Limits](https://pvnode.com/usage).
:::