# 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.

---
## 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 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://: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//.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.