From 4b52922a33e194d704e9ab5e30eebc1aeac91ff9 Mon Sep 17 00:00:00 2001 From: "Dennis L." Date: Mon, 27 Apr 2026 08:32:24 +0200 Subject: [PATCH] restrukturierung --- Dashboard.py => raspi/Dashboard.py | 0 Notification.py => raspi/Notification.py | 0 raspi/README.md | 129 ++++++++++++++++++ USBRead.py => raspi/USBRead.py | 0 gunicorn.conf.py => raspi/gunicorn.conf.py | 0 requirements.txt => raspi/requirements.txt | 0 settings.json => raspi/settings.json | 0 mirror.css => raspi/static/css/mirror.css | 0 dashboard.js => raspi/static/js/dashboard.js | 0 base.html => raspi/templates/base.html | 0 .../templates/dashboard.html | 0 11 files changed, 129 insertions(+) rename Dashboard.py => raspi/Dashboard.py (100%) rename Notification.py => raspi/Notification.py (100%) create mode 100644 raspi/README.md rename USBRead.py => raspi/USBRead.py (100%) rename gunicorn.conf.py => raspi/gunicorn.conf.py (100%) rename requirements.txt => raspi/requirements.txt (100%) rename settings.json => raspi/settings.json (100%) rename mirror.css => raspi/static/css/mirror.css (100%) rename dashboard.js => raspi/static/js/dashboard.js (100%) rename base.html => raspi/templates/base.html (100%) rename dashboard.html => raspi/templates/dashboard.html (100%) diff --git a/Dashboard.py b/raspi/Dashboard.py similarity index 100% rename from Dashboard.py rename to raspi/Dashboard.py diff --git a/Notification.py b/raspi/Notification.py similarity index 100% rename from Notification.py rename to raspi/Notification.py diff --git a/raspi/README.md b/raspi/README.md new file mode 100644 index 0000000..9a2dafb --- /dev/null +++ b/raspi/README.md @@ -0,0 +1,129 @@ +# Smart Mirror · Arduino USB Monitor v3 + +## Projektstruktur + +``` +usb_monitor_v3/ +├── settings.json ← zentrale Konfiguration +├── USBRead.py ← serielle Leseschicht + Parser +├── Notification.py ← SMTP- + WhatsApp-Alerting +├── Dashboard.py ← Flask App Factory +├── gunicorn.conf.py ← Gunicorn-Konfiguration +├── requirements.txt +├── templates/ +│ ├── base.html ← Jinja2 Basis-Layout +│ └── dashboard.html ← Smart-Mirror-Dashboard +└── static/ + ├── css/ + │ └── mirror.css ← Smart-Mirror-Stylesheet + └── js/ + └── dashboard.js ← Polling, Chart, Uhr, Sensor-Tiles +``` + +--- + +## Installation + +```bash +pip install -r requirements.txt + +# Nur bei whatsapp.provider = "twilio": +pip install twilio +``` + +--- + +## Starten + +```bash +# Gunicorn (Produktion, Port 80 → sudo nötig) +sudo gunicorn -c gunicorn.conf.py "Dashboard:create_app()" + +# Ohne Root (Port in settings.json auf z.B. 8080 setzen) +gunicorn -c gunicorn.conf.py "Dashboard:create_app()" + +# Flask direkt (Entwicklung) +python Dashboard.py +``` + +--- + +## settings.json — Referenz + +### `usb` +| Schlüssel | Beschreibung | +|----------------------|--------------------------------------------------| +| `port` | Gerätepfad, z.B. `/dev/ttyACM0` | +| `baud_rate` | Baudrate | +| `reconnect_delay_s` | Sekunden bis Reconnect-Versuch | +| `buffer_size` | Maximale Einträge im Ring-Buffer | + +### `dashboard` +| Schlüssel | Beschreibung | +|----------------------|--------------------------------------------------| +| `host` | Bind-Adresse (`0.0.0.0` = alle Interfaces) | +| `port` | HTTP-Port | +| `poll_interval_ms` | Browser-Polling-Intervall in ms | +| `title` | Titel im Header und Browser-Tab | + +### `smtp` +| Schlüssel | Beschreibung | +|----------------------|--------------------------------------------------| +| `enabled` | `true` / `false` — Kanal an/aus | +| `host` | SMTP-Hostname | +| `port` | SMTP-Port (587 STARTTLS, 465 SSL) | +| `use_tls` | `true` → STARTTLS, `false` → direktes SSL | +| `username` | Login | +| `password` | Passwort | +| `from_address` | Absender | +| `to_addresses` | Empfänger-Array | +| `cooldown_s` | Mindestabstand zwischen Alerts (pro Sensor) | + +### `whatsapp` +| Schlüssel | Beschreibung | +|----------------------|--------------------------------------------------| +| `enabled` | `true` / `false` | +| `provider` | `"twilio"` oder `"callmebot"` | +| `cooldown_s` | Mindestabstand WhatsApp-Alerts (pro Sensor) | + +**Twilio** (`whatsapp.twilio`): +- Account SID + Auth Token aus der Twilio Console +- `from_number`: `"whatsapp:+14155238886"` (Sandbox) oder eigene Nummer +- `to_numbers`: Array mit `"whatsapp:+49..."` +- Einmalige Sandbox-Aktivierung: https://www.twilio.com/console/sms/whatsapp/sandbox + +**CallMeBot** (`whatsapp.callmebot`) — kostenlos, kein Account: +- API-Key einmalig aktivieren: https://www.callmebot.com/blog/free-api-whatsapp-messages/ +- `to_numbers`: Array mit Rufnummern im Format `"+49151..."` + +### `sensors` +Jeder Eintrag im Array beschreibt einen Messkanal: + +| Schlüssel | Beschreibung | +|--------------------|-------------------------------------------------------| +| `name` | Anzeigename | +| `field_index` | Index im `values`-Array (0-basiert) | +| `unit` | Einheit (Anzeige), z.B. `"°C"` | +| `threshold_high` | Oberer Grenzwert (`null` = kein) | +| `threshold_low` | Unterer Grenzwert (`null` = kein) | +| `notify_on_high` | E-Mail + WA senden bei Überschreitung | +| `notify_on_low` | E-Mail + WA senden bei Unterschreitung | + +--- + +## Arduino-Ausgabeformate (automatisch erkannt) + +| Format | Beispiel | +|--------------|--------------------------------| +| Numerisch | `23.5 67.1 4.92` | +| Key=Value | `temp=23.5,hum=67.1,volt=4.92` | +| JSON | `{"temp":23.5,"hum":67.1}` | + +--- + +## Smart Mirror Betrieb + +Für den Einsatz als Smart Mirror empfiehlt sich: +- Chromium im Kiosk-Modus: `chromium-browser --kiosk http://localhost` +- Bildschirm-Timeout deaktivieren: `xset s off && xset -dpms` +- Autostart via `/etc/rc.local` oder systemd (siehe README v2) diff --git a/USBRead.py b/raspi/USBRead.py similarity index 100% rename from USBRead.py rename to raspi/USBRead.py diff --git a/gunicorn.conf.py b/raspi/gunicorn.conf.py similarity index 100% rename from gunicorn.conf.py rename to raspi/gunicorn.conf.py diff --git a/requirements.txt b/raspi/requirements.txt similarity index 100% rename from requirements.txt rename to raspi/requirements.txt diff --git a/settings.json b/raspi/settings.json similarity index 100% rename from settings.json rename to raspi/settings.json diff --git a/mirror.css b/raspi/static/css/mirror.css similarity index 100% rename from mirror.css rename to raspi/static/css/mirror.css diff --git a/dashboard.js b/raspi/static/js/dashboard.js similarity index 100% rename from dashboard.js rename to raspi/static/js/dashboard.js diff --git a/base.html b/raspi/templates/base.html similarity index 100% rename from base.html rename to raspi/templates/base.html diff --git a/dashboard.html b/raspi/templates/dashboard.html similarity index 100% rename from dashboard.html rename to raspi/templates/dashboard.html