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

12 KiB
Raw Blame History

Netatmo Weather Station Plugin

Zeigt die Live-Daten deiner heimischen Netatmo Wetterstation 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


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):

{
  "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.