Files
epaper-dashboard/plugins/NETATMO.md
T
Patrik 5e98b71b82 DOCS-SYNC: README + RECOVERY + NETATMO.md aktualisiert, CHANGELOG neu
README.md:
- Architektur-Diagramm: clock_wordclock + netatmo ergaenzt
- Neue Sektion 'Shared Foundation' (palette.py + plugins/base.py)
- Neue Sektion 'DeepSleep / Energie' (Weckzeiten, CPU-Throttle, /power Route)
- Plugin-Tabelle korrigiert: alle Config-Felder auf aktuellen Stand
  (system: show_uptime/show_load/compact, strava: client_id/secret/refresh_token,
   spotify: Last.fm statt Spotify API, gmail: oauth_token_json,
   minimax: subscription_key, netatmo: client_id/secret/refresh_token)
- Eigenes-Plugin-Sektion: Hinweis auf shared helper-Nutzung
- Quick-Start config.json mit power-Block-Beispiel

RECOVERY.md:
- Neue Sektion 'Display-Refresh aus Admin-UI erzwingen' (POST /api/wake)
- Neue Sektion 'DeepSleep-Fehlkonfiguration' (manueller Fix via SSH/Recovery-AP)

plugins/NETATMO.md:
- Sektion 3: Slot-Tabelle aktualisiert (compact / compact_2x2 / full_4x4)
- Neues V1-Status-Update ASCII-Layout mit allen Sektionen
- Design-Regeln explizit aufgelistet
- Sektion 4 Optionen auf aktuellen Stand (refresh_token statt username/password,
   show_forecast statt show_secondary/show_compass, bar_gradient weg)
- Sektion 6 Technische Details: Forecast-Quelle Open-Meteo, neue interne
  Methoden (_render_compact_2x2, _render_full_4x4, _get_12h_history,
  _get_forecast), shared helper explizit aufgelistet

CHANGELOG.md (neu):
- Keep-a-Changelog-Format mit [Unreleased] fuer aktuelle Aenderungen
- FEAT-DEEPSLEEP + FEAT-NETATMO-06 + REFACTOR-PLUGINS dokumentiert
- 'Earlier' Sektion mit letztem Git-Log der NETATMO-Iterationen
2026-08-31 01:03:26 +02:00

277 lines
12 KiB
Markdown
Raw 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** | `compact`: Große Außen-Temperatur + MIN/MAX + Tag-Status |
| **2×2** | `compact_2x2`: Aussen + Wind/Regen-Bereich + Indoor-Liste |
| **4×4** | `full_4x4`: Volle V1-Status-Update Ansicht (siehe unten) |
### V1-Status-Update Design (4×4)
Die grosse Ansicht ist als **V1-Status-Update** designed — minimal, weisser
Hintergrund, kräftige Akzentfarben, klare Hierarchie:
```
┌──────────────────────────────────────────────────────────────────┐
│ DAHEIM Mo 31.08 00:36 │
├──────────────┬──────────┬─────────────────────────────────────────┤
│ AUSSEN ▮▮▮ │ WIND │ INNEN · 3 │
│ │ N │ ┌─┐ │
│ 12.6° │ 12 │ │M│ Daheim 21.5° │
│ │ km/h │ └─┘ │
│ MIN MAX F │ Bö 24 │ ▰▰▱▱▱▱▱▱ CO₂ 620 ppm ▮ 78% │
│ 13° 21° 67% │ ─────── │ │
│ DRUCK 1014▼ │ REGEN │ ┌─┐ │
│ │ 0.0 │ │2│ Küche 23.5° │
│ 12H VERLAUF │ mm/h │ └─┘ │
│ ╱╲ │ │ ▰▰▰▰▱▱▱▱ CO₂ 980 ppm ▮ 88% │
│ ╱ ╲ │ HEUTE │ │
│ ╱ ╲── │ 6.2 mm │ ┌─┐ │
│ 22°/10° jetzt│ ▮ 82% │ │3│ Schlafen 20.8° │
│ │ │ └─┘ │
│ │ │ ▰▰▰▰▰▱▱ CO₂ 1450 ppm ▮ 41% │
├──────────────┴──────────┴─────────────────────────────────────────┤
│ VORHERSAGE │
│ MO ▮ 0.0 mm ☀ 9° 19° │
│ DI ▮ 2.4 mm ☁ 11° 21° │
│ MI ▮ 8.1 mm ☁ 8° 17° │
└──────────────────────────────────────────────────────────────────┘
```
**Spalten:**
- **Aussen (28%)** — Grosse Aussentemperatur + 4 Stats (MIN/MAX/FEUCHTE/DRUCK) +
12h-Verlaufs-Chart (grüne Linie, 2 Y-Ticks min/max)
- **Wind/Regen (16%)** — beide gestapelt, Wind oben mit Compass und Bö,
Regen unten mit HEUTE-Menge und 1h/24h-Bars; jeder Block hat seine Batterie unten rechts
- **Indoor (36%)** — pro Sensor eine Zeile: rote Tag-Box (M/2/3) | Name | grosser
Temp-Wert (22pt, in Temperatur-Farbe) | CO₂-Bar (gelb/rot je nach ppm) | CO₂-Wert + Batterie
- **Vorhersage (20%)** — pro Tag: Tag-Name + Regentropfen-Icon + Regenmenge in mm +
Wetter-Icon (WMO), darunter riesige Min (blau) / Max (orange)
**Wichtige Design-Regeln:**
- 7 ACeP-Farben nur (kein Grau, keine Verläufe, kein Anti-Aliasing)
- Wichtige Werte (Temps, Regen) dominieren visuell
- Batterie-Icons gehen in den Bottom-Right ihrer Sektion
- Indoor-Sensoren haben rote Tag-Box (NICHT schwarz)
- MIN/MAX kommen aus echter 12h-History (nicht estimated)
- Forecast-Daten dynamisch via `datetime.now() + timedelta`
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 |
| `refresh_token` | secret | — | OAuth2 Refresh-Token (nur RAM, wird on-demand erneuert) |
| `station_filter` | string | `""` | Substring-Filter auf Stations-/Modulname |
| `show_outdoor` | bool | `true` | NAModule1 (Außen) anzeigen |
| `show_wind` | bool | `true` | NAModule2 (Wind) anzeigen |
| `show_rain` | bool | `true` | NAModule3 (Regen) anzeigen |
| `show_indoor` | bool | `true` | Hauptmodul + zusätzliche Indoor-Sensoren anzeigen |
| `show_forecast` | bool | `true` | Open-Meteo 3-Tage-Vorhersage anzeigen |
| `co2_thresholds` | string | `ok@600,warn@1000,alert@1500` | CO₂-Bar Schwellen (ppm) |
| `temp_unit` | select | `C` | `C` oder `F` |
| `wind_unit` | select | `kmh` | `kmh` oder `ms` |
### Auth-Flow (aktualisiert)
Das Plugin verwendet **OAuth2 mit Refresh-Token-Grant** (kein Passwort-Grant mehr).
Beim ersten Setup musst du einmalig einen Refresh-Token holen — das geht z.B. mit
dem Netatmo-Developer-Portal oder dem offiziellen OAuth-Tool. Danach wird der
Token automatisch im RAM gecacht und alle 3h erneuert.
Falls du noch alte `username`/`password`-Config-Felder in deiner `config.json` hast:
diese werden ignoriert. Setze statt dessen `refresh_token`.
### 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 (Refresh-Token-Grant) |
| Endpoints | `POST /oauth2/token`, `GET /api/getstationsdata` |
| Forecast-Quelle | Open-Meteo (`/v1/forecast`) — kein API-Key |
| Token-Lebensdauer | 10800s (3h), Refresh on the fly |
| Cache | In-Memory, kein Disk-IO pro Render |
| Datenquelle Netatmo | Netatmo Cloud (Update alle ~10 Min) |
| Modul-Typen | NAMain, NAModule1..4 |
| `reachable`-Feld | „true" wenn das Modul in den letzten 4h gesehen wurde |
### Wichtige interne Methoden
- `_render_compact(x, y, w, h, ...)` — 1×1-Mini-Ansicht
- `_render_compact_2x2(x, y, w, h, ...)` — 2×2-Ansicht
- `_render_full_4x4(x, y, w, h, ...)` — V1-Status-Update für 4×4
- `_get_12h_history(...)` — 12h-Temperaturverlauf (Quelle: Netatmo `getmeasure` API)
- `_get_forecast(lat, lon, days=3)` — Open-Meteo 3-Tage-Vorhersage
### Shared Helper (aus `plugins/base.py` + `palette.py`)
Das Plugin nutzt konsequent die zentralen Render-Helper:
- `draw_battery()`, `batt_color()` — Batterie-Icon mit 3-stufiger Farbe
- `draw_compass()` — Windrose (mit N/O/S/W-Beschriftung optional)
- `draw_weather_icon()`, `wmo_to_icon()` — 7 Wetter-Zustände (sun/cloud/rain/storm/snow/fog/partly)
- `draw_line_chart()` — 12h-Verlaufs-Chart mit Y-Grid
- `draw_mini_bar()` — 1h/24h-Regen-Bars
- `de_weekday_long/short`, `de_date`, `de_time` — deutsche Datums-/Zeit-Formatter (locale-frei)
- `temp_color()`, `co2_color()` — semantische Farben nach Schwellen
### Was wird pro Refresh gemacht?
1. Prüfe Token-Cache (RAM). Wenn abgelaufen oder fehlend → hole neuen
Token via Refresh-Grant.
2. `GET /api/getstationsdata?get_favorites=false` mit Bearer-Token.
3. Hole 12h-History (`getmeasure`) für MIN/MAX-Berechnung.
4. Hole 3-Tage-Forecast von Open-Meteo.
5. Parse Antwort, filtere nach `station_filter` und sichtbaren Modulen.
6. Rendere je nach Slot-Größe (`compact` / `compact_2x2` / `full_4x4`).
Bei 401 wird der Token-Cache geleert und **einmal** neu authentifiziert.
Wenn das auch fehlschlägt → roter Error-Banner mit der genauen HTTP-Meldung.