Sync to Pi: alle Features die live deployed sind
Aus dem Backup und Live-Pull vom Pi (10.11.3.144): - dashboard.py: Grid-Linien nur im freien Hintergrund (nicht durch Widgets) - templates/index.html: komplett redesigned mit Sidebar + Topbar + Toast + Modal - plugins/clock.py: responsive Layout (1x1 bis 4x4) - plugins/system.py, weather.py, minimax.py: mit Threshold-Bars und Color-Variants - plugins/base.py: NEU — fetch_with_retry Helper (3x retry mit backoff) + render_error_banner für fehlgeschlagene API-Plugins (grosses rotes "!" Icon mit Plugin-Name und Fehler statt Crash) Cleanup: Helfer-Chaos (renderer.py/2/3, design_a/b/c.html, clock_classic.py, 23x clock_*.png, alte test_*.py) wurde bereits im vorherigen Commit entfernt. Co-Authored-By: Hermes <noreply@hermes.local>
This commit is contained in:
co-authored by
Hermes
parent
af9a99a379
commit
1f142f5245
@@ -0,0 +1,176 @@
|
||||
# epaper-dashboard
|
||||
|
||||
Plugin-based dashboard for the **Waveshare 7.3" ACeP 7-Color e-Paper (F) HAT** on Raspberry Pi 4.
|
||||
|
||||
Rendert alle 180s (oder konfigurierbar) ein 800×480px Vollbild auf dem Display.
|
||||
|
||||
## Hardware
|
||||
|
||||
- **Display:** Waveshare 7.3inch ACeP 7-Color e-Paper (F) HAT — 800×480, 7 Farben
|
||||
- **Pi:** Raspberry Pi 4 (oder Zero 2 W mit Einschränkungen)
|
||||
- **Interface:** SPI
|
||||
|
||||
## Architektur
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ epaper-dashboard │
|
||||
├──────────────────┬──────────────────────────┤
|
||||
│ dashboard.py │ admin.py │
|
||||
│ (Renderer) │ (Web Admin UI :8080) │
|
||||
├──────────────────┴──────────────────────────┤
|
||||
│ layout.py · 4×4 Grid · Pack-Algorithmus │
|
||||
├────────────────────────────────────────────┤
|
||||
│ plugins/ (eines pro Widget) │
|
||||
│ clock · weather · system · spotify │
|
||||
│ strava · gmail · minimax · hello │
|
||||
├────────────────────────────────────────────┤
|
||||
│ network_watchdog.py │
|
||||
│ (WiFi AP/Client Management) │
|
||||
├────────────────────────────────────────────┤
|
||||
│ waveshare_epd/ (Vendor-Treiber) │
|
||||
│ epd7in3f.py │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Pi vorbereiten
|
||||
|
||||
```bash
|
||||
sudo apt update && sudo apt install -y python3-pil python3-numpy python3-flask git
|
||||
sudo raspi-config # → Interface Options → SPI → Enable
|
||||
sudo reboot
|
||||
```
|
||||
|
||||
### Setup
|
||||
|
||||
```bash
|
||||
# Repository klonen
|
||||
git clone https://git.pkop.de/Vibecode/epaper-dashboard.git
|
||||
cd epaper-dashboard
|
||||
|
||||
# Config erstellen
|
||||
cp config.example.json config.json
|
||||
# → config.json editieren (Plugins + Layout)
|
||||
|
||||
#waveshare_epd Treiber
|
||||
git clone https://github.com/waveshareteam/Waveshare_GPIO.git waveshare_epd_lib
|
||||
# oder: den waveshare_epd Ordner vom vorherigen Setup übernehmen
|
||||
|
||||
# Services installieren
|
||||
chmod +x install_services.sh
|
||||
./install_services.sh
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
`config.json` — Version 2 Format (empfohlen):
|
||||
|
||||
```json
|
||||
{
|
||||
"version": 2,
|
||||
"refresh_interval_s": 180,
|
||||
"layout": {
|
||||
"grid": { "cols": 4, "rows": 4 },
|
||||
"items": [
|
||||
{ "id": "c1", "plugin": "clock", "x": 0, "y": 0, "w": 2, "h": 2 },
|
||||
{ "id": "w1", "plugin": "weather", "x": 2, "y": 0, "w": 2, "h": 2 },
|
||||
{ "id": "st1", "plugin": "system", "x": 0, "y": 2, "w": 2, "h": 2 },
|
||||
{ "id": "h1", "plugin": "hello", "x": 2, "y": 2, "w": 2, "h": 2 }
|
||||
]
|
||||
},
|
||||
"plugin_configs": {
|
||||
"hello": { "text": "Edit me!", "size": 40 }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Grid:** 4 Spalten × 4 Zeilen = 16 Zellen à 200×120px. `x,y` = Spalte/Zeile oben-links, `w,h` = Breite/Höhe in Zellen.
|
||||
|
||||
### Web Admin
|
||||
|
||||
```
|
||||
http://pi:8080/
|
||||
```
|
||||
|
||||
- **Layout-Editor** — Items per Klick hinzufügen, verschieben, Größe ändern, Auto-Pack
|
||||
- **Plugin-Config** — API-Keys, Locations, etc. pro Widget
|
||||
- **Refresh Now** — sofortiger Display-Refresh
|
||||
- **Netzwerk** — WLAN wechseln ohne SSH
|
||||
|
||||
Default Login: `admin` / `admin` — in `.env` mit `EPAPER_ADMIN_PASSWORD` setzen.
|
||||
|
||||
## Plugins
|
||||
|
||||
| Plugin | Datenquelle | Config-Felder |
|
||||
|--------|-------------|---------------|
|
||||
| `clock` | Systemzeit | — |
|
||||
| `weather` | Open-Meteo (kein API-Key) | `location` (lat,lon), `show_uv`, `show_forecast_hours` |
|
||||
| `system` | Pi CPU/RAM/Uptime | `show_uptime`, `show_load`, `show_temp` |
|
||||
| `spotify` | Spotify Web API | `client_id`, `client_secret` (via Spotify Dev Portal) |
|
||||
| `strava` | Strava API | `access_token`, `club_id` |
|
||||
| `gmail` | Gmail API | `credentials_json` (OAuth2) |
|
||||
| `minimax` | MiniMax AI | `api_key`, `model`, `prompt` |
|
||||
| `hello` | statisch | `text`, `color`, `size` |
|
||||
|
||||
## Eigenes Plugin schreiben
|
||||
|
||||
```python
|
||||
# plugins/my_widget.py
|
||||
from plugins.base import Widget
|
||||
from palette import FG, BG
|
||||
|
||||
class Widget(Widget):
|
||||
name = "my_widget"
|
||||
label = "Mein Widget"
|
||||
description = "Zeigt etwas"
|
||||
category = "info"
|
||||
|
||||
config_schema = [
|
||||
{"key": "api_key", "label": "API Key", "type": "secret"},
|
||||
{"key": "interval", "label": "Intervall (s)", "type": "int", "default": 60},
|
||||
]
|
||||
default_config = {"api_key": "", "interval": 60}
|
||||
|
||||
def fetch(self):
|
||||
return {"value": 42}
|
||||
|
||||
def render(self, draw, fonts, x, y, w, h):
|
||||
d = self.fetch()
|
||||
# w, h sind Pixel (nicht Zellen!)
|
||||
draw.text((x + 10, y + 10), f"Value: {d['value']}",
|
||||
font=fonts["28"], fill=FG)
|
||||
```
|
||||
|
||||
**Palette:** `BLACK, WHITE, RED, GREEN, BLUE, YELLOW, ORANGE` + semantisch `FG, BG, OK, WARN, ALERT, INFO, ACCENT`
|
||||
|
||||
## Services
|
||||
|
||||
```bash
|
||||
systemctl --user enable --now epaper-dashboard
|
||||
systemctl --user enable --now epaper-admin
|
||||
journalctl --user -u epaper-dashboard -f # Logs
|
||||
```
|
||||
|
||||
**Wichtig:** `PrivateTmp=no` in den Service-Files — sonst sieht der Admin-Socket `/tmp/epaper-dashboard.sock` nicht.
|
||||
|
||||
## Display-Einschränkungen
|
||||
|
||||
- **Nur Full-Refresh:** ACeP-Displays vertragen keine schnellen Partial-Refreshes. Minimum 180s.
|
||||
- **Refresh-Dauer:** Ein Full-Refresh dauert ~35-65s. Währenddessen ist das Display leer/flackernd.
|
||||
- **Ghosting:** Leichtes Ghosting bei manchen Farben normal. Display nicht bei direktem Sonnenlicht ablesen.
|
||||
|
||||
## Recovery
|
||||
|
||||
Falls das konfigurierte WLAN nicht erreichbar ist: der Pi startet automatisch einen **Recovery AP**.
|
||||
|
||||
- **SSID:** `epaper-recovery`
|
||||
- **Passwort:** `recovery1234`
|
||||
- **URL:** http://10.42.0.1:8080/
|
||||
|
||||
Dort kannst du ein neues WLAN konfigurieren. Details in `RECOVERY.md`.
|
||||
|
||||
## Lizenz
|
||||
|
||||
Apache 2.0
|
||||
Reference in New Issue
Block a user