pvnodepvnode
  • pvnode.com
  • Studio
  • Pricing
  • Deutsch
  • English
  • API Reference
Product
  • Studio
  • API Documentation
  • API Reference
  • Pricing
Resources
  • Quickstart
  • Integrations
Legal
  • Imprint
  • Privacy
  • Terms
  • Licenses
pvnodepvnode

© 2026 pvnode. All rights reserved.

linkedin
EinführungSchnellstartMigration von V1
Standorte & Daten
    Standorte & SolarflächenPrognosenHistorische DatenDaten-UploadKalibrierung & Monitoring
Guides
Enterprise
Integrationen
    Eigene Integration bauenHome AssistantevccSolectrusioBroker
(Archiv) V1 API
powered by Zudoku
Integrationen

Integrationen bauen

Die API-Referenz beschreibt, was die Endpunkte tun. Diese Seite beschreibt, wie sich ein Client verhalten sollte, der unbeaufsichtigt bei jemandem zu Hause läuft — Home Assistant, ioBroker, ... — damit er sparsam, selbstheilend und angenehm einzurichten ist.

Die folgenden Regeln sind die, denen auch die offizielle Home-Assistant-Integration folgt. Wer einen eigenen Client schreibt, umgeht damit die beiden Fehler, die uns am häufigsten begegnen: das Kontingent des Nutzers für zwischengespeicherte Daten zu verbrennen, und bei einem Planwechsel kaputtzugehen.

Die wichtigste Regel: Auch eine Cache-Antwort kostet eine Anfrage. pvnode rechnet nichts nach Zeitplan neu — wer vor next_poll_at erneut fragt, bekommt exakt dieselbe Antwort und zahlt trotzdem dafür.

1. Einrichtung: Key erfragen, dann den Standort auswählen lassen

Verlangen Sie nie, dass ein Nutzer eine site_id einfügt. Standorte zu lesen ist auf jedem Plan offen, ein Client kann sie also immer auflisten:

TerminalCode
GET /v2/sites/ Authorization: Bearer YOUR_API_KEY
Code
[ {"id": "site_ai8wsa9jvu3y6uqt...", "name": "Zuhause", "timezone": "Europe/Berlin"}, {"id": "site_rv8wm5k2p1x4c7t8...", "name": "Garage", "timezone": "Europe/Berlin"} ]

Der empfohlene Ablauf hat zwei Schritte:

  1. API-Key. Prüfen Sie ihn mit GET /v2/sites/. Eine 401 bedeutet, dass der Key falsch ist — und Sie haben dafür kein Prognose-Kontingent ausgegeben.
  2. Standort-Auswahl. Zeigen Sie die Namen, speichern Sie die id. Bei genau einem Standort überspringen Sie den Schritt und wählen ihn automatisch.

Nutzen Sie die site_id als stabile Identität der Konfiguration — daran erkennen Sie eine doppelte Einrichtung, und sie überlebt das Umbenennen des Standorts.

Derselbe Aufruf liefert die Strings mit slope, orientation und power_kw — genau das, was Sie für Namen pro Solarfläche brauchen. Strings haben kein Namensfeld, leiten Sie also einen ab ("Süd 30° · 9,9 kWp"), statt einen rohen Index anzuzeigen.

GET /v2/sites/ und GET /v2/sites/{site_id} zählen nicht auf das Prognose-Kontingent und tragen keine RequestLimit-*-Header. Rufen Sie sie bei der Einrichtung auf und dann, wenn sich die Stringliste geändert haben könnte — aber nicht bei jeder Aktualisierung; günstig ist nicht kostenlos.

2. Den Plan erkennen, nicht fest einprogrammieren

Jede Prognose-Antwort trägt beides:

Code
"included": ["default", "strings"], "available": ["default", "weather", "irradiance", "clearsky", "strings", "variability"]

included ist, was Sie angefragt haben. available ist, was der Plan erlauben würde. Wenn Sie Ihren Funktionsumfang aus available ableiten, braucht ein Planwechsel weder ein neues Release noch eine Aktion des Nutzers:

  • Erste Anfrage: konservativ fragen — Plan-gebundene Gruppen weglassen.
  • available lesen. Steht dort eine Gruppe, die Sie wollen, fragen Sie sie ab der nächsten Abfrage mit an.
  • Bei einem Downgrade ist available eine Antwort veraltet: Es kann eine Gruppe versprechen, die gerade entzogen wurde. Behandeln Sie die daraus folgende 403 als Signal, nicht als Fehler — Gruppe streichen, weiterlaufen.

Heute ist variability die einzige plangebundene Gruppe. Sie ohne Berechtigung anzufragen wird abgelehnt, bevor die Anfrage gezählt wird — ein Probelauf kostet also nichts.

Code
want_variability = "variability" in previous_response.get("available", [])

Bei einer frischen Installation gibt es keine vorherige Antwort — fragen Sie dann einmal mit der Gruppe an. Die 403 ist kostenlos und klärt die Frage sofort.

3. Auf next_poll_at pollen, nie auf einen eigenen Takt

next_poll_at ist der früheste Zeitpunkt, zu dem eine Anfrage eine neue Prognose liefert:

Code
"computed_at": "2026-06-09T08:00:00+02:00", "next_poll_at": "2026-06-09T12:00:00+02:00"

Leiten Sie Ihre nächste Abfrage daraus ab, statt aus einem festen Intervall. Ein fest verdrahtetes „alle 30 Minuten" ist in beide Richtungen falsch: verschwenderisch bei einem Plan mit einem Update pro Tag, veraltet bei einem Plan mit 96 Updates pro Tag.

Code
delay = parse(response["next_poll_at"]) - now() + timedelta(seconds=30) delay = min(max(delay, timedelta(minutes=1)), timedelta(hours=24))

Drei Details, die sich zu übernehmen lohnen:

  • Ein kleiner Offset (etwa 30 s) verhindert, dass Sie kurz vor der Slot-Grenze landen und doch die alte Antwort bekommen.
  • Das Ergebnis beschränken. Nicht, weil ein Serverfehler erwartet wird, sondern weil eine negative oder absurde Verzögerung sonst zur Anfrageschleife wird. Eine Minute bis 24 Stunden ist ein vernünftiger Rahmen.
  • Einen Rückfall vorsehen. Fehlt das Feld, wählen Sie ein konservatives Intervall (eine Stunde) und laufen weiter, statt stehenzubleiben.

next_poll_at ist eine Empfehlung, keine Zusage — eine andere Anfrage kann eine frühere Neuberechnung auslösen. Darauf zu pollen ist die günstigste korrekte Strategie.

Bauen Sie den Zeitplan nicht selbst nach. Es liegt nahe, sich auszurechnen, wann die Slots liegen, und einen Timer danach zu stellen. Tun Sie es nicht: Wie sie verteilt sind, wird sich ändern — wir wollen nachts, wenn nichts erzeugt wird, weniger davon vergeben und dafür mehr in den Stunden, auf die es ankommt. Ein Client, der das Feld liest, geht das automatisch mit. Einer, der sich seinen Takt selbst ausgerechnet hat, fragt irgendwann still zu den falschen Zeiten ab.

4. Ein Neustart darf keine Anfrage kosten

Speichern Sie die letzte Antwort zusammen mit ihrem next_poll_at. Liegt dieser Zeitpunkt beim Start noch in der Zukunft, stellen Sie die gespeicherten Daten wieder her und zeigen sie sofort an — ohne die API aufzurufen.

Code
Start → gespeicherte Antwort laden → next_poll_at noch in der Zukunft? → verwenden, nächste Abfrage planen → sonst → abrufen

Ohne das verbrennt jeder Neustart, jedes Neuladen der Konfiguration und jede Absturzschleife Kontingent für Daten, die der Client bereits hatte. Bei einem Plan mit einem Update pro Tag können ein paar Neustarts den Tag komplett aufbrauchen.

Dem gespeicherten available dürfen Sie beim Wiederherstellen trauen: Es hält die Berechtigung des Plans fest, nicht das, was zufällig angefragt wurde.

5. Werte zwischen den Abfragen lokal weiterbewegen

Die Prognose ist eine 15-Minuten-Zeitreihe über mehrere Tage. Werte wie „Leistung jetzt", „Restenergie heute" oder „Zeitpunkt des Maximums" können Sie aus Daten ableiten, die Sie schon haben — sie brauchen keine neue Anfrage.

Berechnen Sie sie über einen lokalen Takt (z.B. alle 5 Minuten) aus der gespeicherten Zeitreihe neu und aktualisieren Sie Ihre Oberfläche. So bekommt auch ein Nutzer mit einem Update pro Tag einen Wert, der sich über den Tag bewegt.

Nur die Prognosekurve muss abgefragt werden. Alles, was Sie daraus ablesen, nicht.

6. Die Kontingent-Header auslesen

Jede Prognose-Antwort — auch die 429 — trägt:

Code
RequestLimit-Limit: 10000 RequestLimit-Used: 4231 RequestLimit-Remaining: 5769 RequestLimit-Reset: 2026-09-01T00:00:00Z

Remaining anzuzeigen lohnt sich: Es macht die Kosten eines manuellen Aktualisieren-Knopfs sichtbar und erklärt eine stehengebliebene Integration auf einen Blick.

Limit und Remaining sind Strings. Auf Plänen ohne Deckel enthalten sie wörtlich unmetered statt einer Zahl. Parsen Sie defensiv — int(header) scheitert bei diesen Nutzern.

Der Zähler läuft pro (Nutzer, Endpunkt, Monat). Für einen Client folgen daraus zwei Dinge:

  • Die Zahlen gelten kontoweit, nicht pro Standort. Wenn Sie mehrere Standorte unterstützen, beschriften Sie den Wert nicht mit „verbleibende Anfragen für diesen Standort" — jede Instanz zeigt denselben Wert.
  • Prognose und Historie haben getrennte Budgets. Das eine zu verbrauchen berührt das andere nicht.

Bei einer 429 hören Sie bis RequestLimit-Reset mit dem Pollen auf, statt es erneut zu versuchen. Das Kontingent setzt sich am 1. des Folgemonats um 00:00 UTC zurück.

7. Fehlerbehandlung

pvnode nutzt 403 für mehrere voneinander unabhängige Situationen, und ein guter Client reagiert auf jede anders. Unterscheiden Sie sie am detail-Text:

Statusdetail enthältBedeutungEmpfohlene Reaktion
401—Key ungültig oder widerrufenNach einem neuen Key fragen; nicht in Schleife wiederholen.
403variabilityPlan ohne BandKein Fehler. Gruppe streichen, einmal wiederholen.
403does not includePlan ohne Zugang zur Forecast APIAnhalten, den nötigen Plan benennen.
403inactive / site limitStandort nach Downgrade deaktiviertAnhalten, auf Upgrade oder Löschen eines Standorts hinweisen.
404—Standort gelöschtAnhalten, zur Neukonfiguration auffordern.
429—Monatskontingent aufgebrauchtBis RequestLimit-Reset warten und es anzeigen.
5xx—VorübergehendMit Backoff wiederholen, gespeicherte Prognose weiter zeigen.

Ein vorübergehender Fehler sollte die Oberfläche nie leeren. Lassen Sie die letzte gute Prognose stehen und markieren Sie sie als veraltet — eine Prognose von vor einer Stunde ist immer noch eine brauchbare Prognose.

8. Den Client identifizieren

Senden Sie einen User-Agent, der Ihre Integration und deren Version nennt:

Code
User-Agent: my-integration/1.4.0 SomePlatform/2026.8

Er reist auf Anfragen mit, die ohnehin stattfinden, und enthält nichts über den Nutzer. Er zeigt uns, welche Integrationen tatsächlich im Einsatz sind, und lässt uns Maintainer erreichen, bevor eine Änderung sie trifft.

Checkliste

  • Standort über GET /v2/sites/ gewählt
  • site_id ist die stabile Identität der Konfiguration
  • Funktionsumfang aus available abgeleitet, nicht aus fest verdrahteten Plannamen
  • Eine entzogene Gruppe führt zu einem erneuten Versuch, nicht zu einem Setup-Fehler
  • Poll-Intervall aus next_poll_at, beschränkt, mit Rückfall
  • Letzte Antwort gespeichert — ein Neustart kostet keine Anfrage
  • Abgeleitete Werte zwischen den Abfragen lokal neu berechnet
  • RequestLimit-* defensiv geparst (unmetered!) und angezeigt
  • 429 wartet bis Reset
  • Die drei Bedeutungen von 403 getrennt behandelt
  • Veraltete Daten bleiben bei einer Störung sichtbar
  • User-Agent identifiziert den Client

Fragen, oder fehlt etwas? Schreiben Sie an support@pvnode.com.

Last modified on August 18, 2026
IntegrationenHome Assistant
On this page
  • 1. Einrichtung: Key erfragen, dann den Standort auswählen lassen
  • 2. Den Plan erkennen, nicht fest einprogrammieren
  • 3. Auf next_poll_at pollen, nie auf einen eigenen Takt
  • 4. Ein Neustart darf keine Anfrage kosten
  • 5. Werte zwischen den Abfragen lokal weiterbewegen
  • 6. Die Kontingent-Header auslesen
  • 7. Fehlerbehandlung
  • 8. Den Client identifizieren
  • Checkliste
JSON
JSON
JSON