Files
hermes 25b0432757 FEAT-NETATMO-01: Netatmo Weather Station Plugin
OAuth2 Password-Grant + Refresh-Token on-the-fly. Holt sich automatisch
einen neuen Access-Token wenn der alte abläuft (3h Gültigkeit).

Module: NAMain (Indoor), NAModule1 (Outdoor), NAModule2 (Wind),
NAModule3 (Regen), NAModule4 (Extra Indoor).

Slot-responsive:
  1x1 — Outdoor-Temp prominent + Mini-Status
  4x1 — Indoor | Outdoor | Wind/Regen kompakt (3 Spalten)
  1x4 — Vertikale Liste aller Module
  2x2 — Indoor-Card (mit CO2-Bar) + Outdoor-Card + Wind/Regen-Bereich
  4x4 — Volle Ansicht mit Min/Max, Windrose, Timestamps

Config-Optionen:
  client_id/client_secret/username/password (secrets via Admin-UI)
  station_filter (substring-match für Multi-Setup)
  show_indoor/outdoor/wind/rain/compass/secondary (bools)
  co2_thresholds (ppm, default ok@600,warn@1000,alert@1500)
  temp_unit (C/F), wind_unit (kmh/ms)

Plus:
  - plugins/NETATMO.md: vollständige Doku (Setup, Optionen, Diagnose)
  - config.netatmo.example.json: copy-paste Beispiel-Config
  - layout.py: netatmo default-size = 4x4 (4 Sub-Cards brauchen Platz)
  - README.md: Plugin-Tabelle erweitert

Verifiziert: /api/plugins.json listet netatmo, Auto-Loader erkennt es,
Admin-UI zeigt das Config-Form.
2026-08-29 18:35:29 +04:00

201 lines
7.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Netatmo Weather Station Plugin
Zeigt die Live-Daten deiner heimischen [Netatmo Wetterstation](https://www.netatmo.com/de-de/weather/weatherstation)
auf dem 7.3″ ACeP Dashboard: Indoor-Temperatur, CO₂, Luftfeuchte, Luftdruck,
Outdoor-Werte, Wind (Stärke + Böen + Richtung mit Windrose) und Regenmengen.
Funktioniert mit **jeder** Netatmo-Konfiguration (Hauptmodul + beliebige
Zusatzmodule). Module, die du nicht hast, werden automatisch weggelassen.
![Netatmo 4×4](docs/netatmo_4x4.png)
---
## 1. Netatmo-App registrieren
Damit das Plugin Daten abrufen darf, brauchst du eine App-Registrierung
bei Netatmo. Das ist einmalig und kostenlos.
1. Gehe zu <https://dev.netatmo.com/apps/> und logge dich mit deinem
Netatmo-Account ein.
2. Klicke **Create an App**.
3. Fülle das Formular aus:
- **Name**: z. B. „epaper-dashboard"
- **Description**: z. B. „Wetterdaten auf meinem ePaper-Display"
- **Data Protection Officer**: nicht erforderlich für eine persönliche App
4. Bei den **Scopes** wähle mindestens **`read_station`** aus
(Standard-Scope der Weather API). Mehr brauchst du für dieses Plugin nicht.
5. Speichern. Du bekommst **Client-ID** und **Client-Secret** angezeigt —
die brauchst du gleich.
> Hinweis: Netatmo verwendet **OAuth2 mit Password-Grant** für die
> Weather API (kein Browser-Redirect nötig). Dein Passwort wird nur
> lokal für den initialen Token verwendet — es wird **nie** auf der
> Festplatte persistiert, sondern liegt nur im RAM des laufenden
> Dashboard-Prozesses.
---
## 2. Plugin konfigurieren
### Option A — über die Admin-Weboberfläche (empfohlen)
`http://<pi>:8080/` öffnen, in der Sidebar das Widget **Netatmo**
auswählen und die Werte eintragen:
| Feld | Wert |
|---|---|
| Client-ID | von dev.netatmo.com/apps |
| Client-Secret | von dev.netatmo.com/apps |
| Username | deine Netatmo-Login-E-Mail |
| Password | dein Netatmo-Passwort |
| Station (Filter) | leer lassen, wenn du nur eine Station hast |
Speichern. Klicke **Refresh Now** — wenn alles passt, sollten nach
~30s die ersten Daten erscheinen.
### Option B — direkt in `config.json`
Unter `plugin_configs.netatmo` eintragen (Beispiel siehe
[`config.netatmo.example.json`](config.netatmo.example.json)):
```json
{
"plugin_configs": {
"netatmo": {
"client_id": "abc123...",
"client_secret": "def456...",
"username": "du@example.com",
"password": "GEHEIM",
"station_filter": "",
"show_indoor": true,
"show_outdoor": true,
"show_wind": true,
"show_rain": true,
"show_compass": true,
"show_secondary": true,
"co2_thresholds": "ok@600,warn@1000,alert@1500",
"bar_gradient": true,
"temp_unit": "C",
"wind_unit": "kmh"
}
}
}
```
> ⚠️ Secrets in `config.json` sind auf dem Pi persistent (lokal in
> `/home/<user>/.hermes/projects/pi/config.json`). Wenn du das
> vermeiden willst, nimm die Admin-UI — die legt sie genauso ab, aber
> du siehst die Werte nie im Klartext-Editor.
---
## 3. Layout zuweisen
In der Admin-UI ein Netatmo-Widget auf das Grid ziehen. Das Plugin ist
**responsive**: dieselbe Konfiguration sieht auf jedem Slot gut aus.
| Slot | Was du siehst |
|---|---|
| **1×1** | Große Außen-Temperatur, Mini-CO₂/Feuchte-Status |
| **2×1** | Outdoor-Temperatur + Wind-Geschwindigkeit kompakt |
| **4×1** | Indoor · Outdoor · Wind/Regen — drei Spalten |
| **1×4** | Vertikale Liste aller Module |
| **2×2** | Indoor-Card (mit CO₂-Bar) + Outdoor-Card + Wind/Regen-Bereich |
| **4×4** | Volle Ansicht mit allen Modulen, Min/Max, Windrose |
Das Plugin priorisiert bei der Layout-Wahl **wide/tall** vor `small`,
damit 4×1- und 1×4-Slots nicht in die Mini-Ansicht fallen.
---
## 4. Optionen im Detail
| Option | Typ | Default | Bedeutung |
|---|---|---|---|
| `client_id` | secret | — | Netatmo App Client-ID |
| `client_secret` | secret | — | Netatmo App Client-Secret |
| `username` | secret | — | Netatmo Login (E-Mail) |
| `password` | secret | — | Netatmo Passwort (nur RAM) |
| `station_filter` | string | `""` | Substring-Filter auf Stations-/Modulname |
| `show_indoor` | bool | `true` | Hauptmodul + zusätzliche Indoor-Sensoren anzeigen |
| `show_outdoor` | bool | `true` | NAModule1 (Außen) anzeigen |
| `show_wind` | bool | `true` | NAModule2 (Wind) anzeigen |
| `show_rain` | bool | `true` | NAModule3 (Regen) anzeigen |
| `show_compass` | bool | `true` | Windrose in der Wind-Card zeichnen |
| `show_secondary` | bool | `true` | Min/Max + letzte Aktualisierung |
| `co2_thresholds` | string | `ok@600,warn@1000,alert@1500` | CO₂-Bar Schwellen (ppm) |
| `bar_gradient` | bool | `true` | Verlaufsmodus der Bar |
| `temp_unit` | select | `C` | `C` oder `F` |
| `wind_unit` | select | `kmh` | `kmh` oder `ms` |
### CO₂-Schwellen anpassen
`co2_thresholds` ist ein String im Format `farbe@ppm_in_ppm`.
Mehrere Stufen durch Komma trennen:
- `ok@600,warn@1000,alert@1500` — Netatmo-Default-Empfehlungen
- `ok@800,warn@1200` — nur 2 Stufen (kompakt)
- `ok@1000,warn@1500,alert@2000` — strenger (z. B. für Schlafzimmer)
### Station-Filter
Wenn du mehrere Stationen hast (z. B. „Home" und „Office"), kannst du
über `station_filter` einen Substring matchen. Erst wird der
Stationsname geprüft, dann die Modulnamen. Leer = erste Station.
---
## 5. Fehlerdiagnose
### Auth-Fehler (HTTP 401)
- Stimmen Client-ID/Secret mit dem Eintrag auf dev.netatmo.com/apps überein?
- Stimmt das Passwort (case-sensitive)?
- Wurde deine App bei Netatmo evtl. deaktiviert?
→ Plugin setzt den Token-Cache automatisch zurück, beim nächsten Render
wird ein neuer Token geholt.
### "Keine Station gefunden"
- Hat deine Station in den letzten 4h Daten an Netatmo geschickt?
(Netatmo markiert sie sonst als offline.)
- Stimmt der `station_filter`? Wenn du dort z. B. „Home" eingibst, aber
die Station heißt „Home Office", passt es trotzdem (Substring-Match).
Leer = erste Station.
### "API nicht erreichbar"
- Pi hat Internet? (`ping api.netatmo.net`)
- DNS? (`nslookup api.netatmo.net`)
### Werte fehlen / sind 0
- Manche Datenpunkte sind nur in der **Paid**-Subscription verfügbar
(z. B. Historische Daten > 1h). Aktuelle Werte sind immer frei.
---
## 6. Technische Details
| Aspekt | Wert |
|---|---|
| API-Version | Netatmo Connect OAuth2 |
| Endpoints | `POST /oauth2/token`, `GET /api/getstationsdata` |
| Token-Lebensdauer | 10800s (3h), Refresh on the fly |
| Cache | In-Memory, kein Disk-IO pro Render |
| Datenquelle | Netatmo Cloud (Update alle ~10 Min) |
| Modul-Typen | NAMain, NAModule1..4 |
| `reachable`-Feld | „true" wenn das Modul in den letzten 4h gesehen wurde |
### Was wird pro Refresh gemacht?
1. Prüfe Token-Cache (RAM). Wenn abgelaufen oder fehlend → hole neuen
Token via Password-Grant (initial) oder Refresh-Grant.
2. `GET /api/getstationsdata?get_favorites=false` mit Bearer-Token.
3. Parse Antwort, filtere nach `station_filter` und sichtbaren Modulen.
4. Rendere je nach Slot-Größe (`small` / `wide` / `tall` / `standard`).
Bei 401 wird der Token-Cache geleert und **einmal** neu authentifiziert.
Wenn das auch fehlschlägt → roter Error-Banner mit der genauen HTTP-Meldung.