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:
Code
Code
Der empfohlene Ablauf hat zwei Schritte:
- 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. - 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 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.
availablelesen. Steht dort eine Gruppe, die Sie wollen, fragen Sie sie ab der nächsten Abfrage mit an.- Bei einem Downgrade ist
availableeine 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
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
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
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
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
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:
| Status | detail enthält | Bedeutung | Empfohlene Reaktion |
|---|---|---|---|
| 401 | — | Key ungültig oder widerrufen | Nach einem neuen Key fragen; nicht in Schleife wiederholen. |
| 403 | variability | Plan ohne Band | Kein Fehler. Gruppe streichen, einmal wiederholen. |
| 403 | does not include | Plan ohne Zugang zur Forecast API | Anhalten, den nötigen Plan benennen. |
| 403 | inactive / site limit | Standort nach Downgrade deaktiviert | Anhalten, auf Upgrade oder Löschen eines Standorts hinweisen. |
| 404 | — | Standort gelöscht | Anhalten, zur Neukonfiguration auffordern. |
| 429 | — | Monatskontingent aufgebraucht | Bis RequestLimit-Reset warten und es anzeigen. |
| 5xx | — | Vorübergehend | Mit 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
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_idist die stabile Identität der Konfiguration - Funktionsumfang aus
availableabgeleitet, 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-Agentidentifiziert den Client
Fragen, oder fehlt etwas? Schreiben Sie an support@pvnode.com.