Files
epaper-dashboard/README.md
T
ki 28124c5617 Initial commit: epaper-dashboard for 7.3" ACeP 7-Color display
- dashboard.py: plugin-based renderer with 4x4 grid layout
- admin.py: web UI with layout editor + plugin configs
- layout.py: pack algorithm, item placement, grid system
- plugins/: clock, weather, system, spotify, strava, gmail, minimax, hello
- network_watchdog.py: WiFi AP/client mode management
- waveshare_epd_init.py: vendor driver stub
2026-08-26 14:12:43 +04:00

2.7 KiB

7.3" ePaper Dashboard

Plugin-basiertes Dashboard für Waveshare 7.3-inch ACeP 7-Color e-Paper (F) HAT auf einem Raspberry Pi 4.

Architektur

  • Renderer (dashboard.py): Lädt config.json, instanziiert Plugins, refresht das Display alle refresh_interval_s Sekunden (≥180 empfohlen). Reagiert auf Live-Trigger via Unix-Socket.
  • Web-Admin (admin.py): HTTP Basic Auth, konfiguriert Slots, Plugins und Secrets im Browser. Triggert Live-Refresh.
  • Plugins (plugins/): Jedes Widget ist ein Python-Modul mit Widget-Klasse (siehe plugins/base.py). Eigenes Plugin = eine Datei in plugins/.
  • Templates (templates/index.html): Single-Page-UI, auto-reload-fähig.

Setup

# Auf dem Pi:
sudo apt install python3-pil python3-numpy python3-flask git
git clone <dieses repo>  # oder rsync von deinem Dev-Rechner
cd port/
# SPI in /boot/firmware/config.txt aktivieren (dtparam=spi=on)
# Reboot
python3 admin.py &
python3 dashboard.py &

Web-UI: http://pi:8080/
Default Login: admin / admin — bitte EPAPER_ADMIN_PASSWORD in .env setzen.

Plugin schreiben

Eine Datei plugins/my_widget.py:

from plugins.base import Widget
from palette import FG, INFO

class Widget(Widget):
    name = "my_widget"
    label = "Mein Widget"
    description = "Zeigt etwas Nützliches"
    category = "info"
    
    config_schema = [
        {"key": "api_key", "label": "API Key", "type": "secret"},
        {"key": "interval", "label": "Intervall (Sekunden)", "type": "int", "default": 60},
        {"key": "show_extra", "label": "Extra anzeigen", "type": "bool", "default": True},
    ]
    default_config = {"api_key": "", "interval": 60, "show_extra": True}
    
    def fetch(self):
        # Daten holen (API call, etc.)
        return {"value": 42}
    
    def render(self, draw, fonts, x, y, w, h):
        # In den Slot zeichnen
        d = self.fetch()
        draw.text((x + 10, y + 10), f"Value: {d['value']}", font=fonts["28"], fill=FG)

Feld-Typen: string, int, float, bool, secret (write-only), select (mit choices), lat_lon.

Palette (aus palette.py): BLACK, WHITE, GREEN, BLUE, RED, YELLOW, ORANGE + semantisch FG, BG, OK, WARN, ALERT, INFO, ACCENT.

Mitgelieferte Plugins

  • clock — Uhrzeit / Datum
  • weather — Open-Meteo Wetter (kein API-Key)
  • system — Pi CPU/RAM/Uptime
  • hello — Demo
  • spotify — Last.fm Scrobble
  • strava — Strava Aktivitäten
  • gmail — Gmail Unread

Einschränkungen

  • Full Refresh only: ACeP-Displays vertragen keine schnellen Partial-Refreshes (Verschleiß). Das Hersteller-empfohlene Minimum ist 180s.
  • Kein Live-Websocket: Snapshot wird per Refresh-Now-Button ausgelöst. Bei Bedarf ergänzbar.