MeshDD-Bot/docs/bot-beschreibung.md
ppfeiffer eda9177b54 chore: Docker-Dateien und alle Docker-Referenzen entfernt
- Dockerfile, docker-compose.yml, .dockerignore gelöscht
- CHANGELOG.md: Einträge v0.06.01 (Docker-Support) und v0.07.00 entfernt
- docs/bot-beschreibung.md: Docker-Abschnitte und Tabellenzeilen bereinigt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 22:56:36 +01:00

580 lines
24 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# MeshDD-Bot — Vollständige Beschreibung
> Aktueller Stand: **v0.08.09** · Letztes Update: 2026-02-19
---
## Inhaltsverzeichnis
1. [Überblick](#überblick)
2. [Architektur](#architektur)
3. [Komponenten im Detail](#komponenten-im-detail)
4. [Bot-Kommandos](#bot-kommandos)
5. [Weboberfläche & Seiten](#weboberfläche--seiten)
6. [REST-API-Referenz](#rest-api-referenz)
7. [Zugriffsrechte](#zugriffsrechte)
8. [Konfiguration](#konfiguration)
9. [Datenbank](#datenbank)
10. [Deployment](#deployment)
11. [Wichtige Erweiterungsschritte](#wichtige-erweiterungsschritte)
---
## Überblick
**MeshDD-Bot** ist ein Python-basierter Bot für **Meshtastic**-Funknetze mit integriertem Web-Dashboard. Er verbindet sich per TCP mit einem lokalen Meshtastic-Node, empfängt und speichert alle Pakete im Netz, beantwortet Bot-Kommandos und stellt eine browserbasierte Oberfläche für Echtzeit-Monitoring, Verwaltung und Notfall-Warnsystem-Integration bereit.
**Hauptmerkmale:**
- Meshtastic TCP-Verbindung mit automatischem Reconnect
- Bot-Kommandos (Ping, Wetter, Node-Info, Mesh-Statistiken u.a.)
- Echtzeit-Web-Dashboard via WebSocket
- Interaktive Leaflet-Karte aller Nodes
- Zeitgesteuerter Scheduler (Cron-Ausdrücke)
- NINA BBK Warnmeldungs-Integration (warnung.bund.de)
- Benutzerverwaltung mit Rollen (public / user / admin)
- Hot-Reload für alle Konfigurationsdateien
- Paket-Log mit Typ-Filterung
---
## Architektur
```
┌─────────────────────────────────────────────────────┐
│ main.py │
│ asyncio event loop + threading für Meshtastic │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ MeshBot │ │Scheduler │ │ NinaBot │ │
│ │ bot.py │ │scheduler │ │ nina.py │ │
│ └────┬─────┘ │ .py │ └────────┬─────────┘ │
│ │ └────┬─────┘ │ │
│ ┌────▼─────────────▼─────────────────▼──────────┐ │
│ │ WebSocketManager │ │
│ │ webserver.py (aiohttp) │ │
│ └───────────────────┬───────────────────────────┘ │
│ │ │
│ ┌───────────────────▼───────────────────────────┐ │
│ │ Database (aiosqlite) │ │
│ │ database.py │ │
│ └───────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
│ TCP │ HTTP
▼ ▼
Meshtastic-Node Browser-Client
(192.168.11.4:4403) (Bootstrap 5.3 / Tabler)
```
### Technologie-Stack
| Schicht | Technologie |
|---|---|
| Sprache | Python 3.12 |
| Async-Framework | asyncio + aiohttp |
| Meshtastic | meshtastic-python (TCPInterface) |
| Event-Bus | PyPubSub |
| Datenbank | SQLite via aiosqlite |
| Web-Server | aiohttp + WebSocket |
| Auth | bcrypt, aiohttp-session, EncryptedCookieStorage |
| Frontend | Bootstrap 5.3, Tabler 1.4.0, Bootstrap Icons |
| Karte | Leaflet.js |
| Charts | Chart.js |
| NINA-API | aiohttp (async HTTP-Polling) |
| Konfiguration | YAML (config.yaml, scheduler.yaml, nina.yaml) |
| Deployment | systemd Service |
---
## Komponenten im Detail
### `main.py` — Einstiegspunkt
Startet alle Subsysteme in der richtigen Reihenfolge:
1. SQLite-Datenbank verbinden
2. `WebSocketManager` erzeugen
3. `MeshBot` (mit Loop-Referenz)
4. `Scheduler` (referenziert Bot + WS-Manager)
5. `NinaBot` (referenziert Bot's `send_message` + WS-Manager)
6. `WebServer` starten
7. Meshtastic-Verbindung in separatem Thread starten
8. Config-Watcher, Scheduler-Watcher, NINA-Watcher als asyncio-Tasks
9. Auf SIGINT/SIGTERM warten → sauberer Shutdown
### `meshbot/bot.py` — MeshBot
Kernklasse für die Meshtastic-Integration:
- **Verbindung:** `TCPInterface` über Host/Port aus `config.yaml`
- **PubSub-Subscriptions** (registriert *vor* dem Konstruktor):
- `meshtastic.receive` → Paket empfangen
- `meshtastic.connection.established` → Verbindung hergestellt
- `meshtastic.connection.lost` → Verbindung verloren
- `meshtastic.node.updated` → Node-Update
- **Race-Condition-Fix:** `threading.Event` wartet nach dem Konstruktor bis zu 10 s auf `connection.established`; Fallback-Initialisierung nur bei echtem Ausbleiben
- **Paket-Handler:** Extrahiert portnum, from/to-IDs, SNR, RSSI, Hop-Infos; erstellt `payload_summary` je Pakettyp
- **Nachrichtenversand:** `_send_text()` teilt lange Nachrichten automatisch mit `[x/y]`-Nummerierung (max. 170 Byte); 3 Sekunden Pause zwischen Teilen
- **Node-Config:** `get_node_config()` liest LoRa, Device, Channels, Position, Power, Bluetooth, Network via Protobuf
**Unterstützte Pakettypen mit Payload-Zusammenfassung:**
| Portnum | Gespeicherte Felder |
|---|---|
| `TEXT_MESSAGE_APP` | Nachrichtentext |
| `POSITION_APP` | lat, lon, alt, Geschwindigkeit, Satelliten |
| `TELEMETRY_APP` | Akku, Spannung, CH-Util, TX-Util, Temp, Feuchte, Druck |
| `NODEINFO_APP` | long_name, short_name, hw_model |
| `ROUTING_APP` | Fehlercode |
| `TRACEROUTE_APP` | Hop-Anzahl, Route |
| `NEIGHBORINFO_APP` | Anzahl Nachbarn |
### `meshbot/nina.py` — NinaBot
Integration des **NINA Warn-App des BBK** (Bundesamt für Bevölkerungsschutz und Katastrophenhilfe):
- **API-Basis:** `https://warnung.bund.de/api31`
- **Duales Polling** pro Zyklus:
1. **Dashboard-Endpunkt** (`/dashboard/{AGS12}.json`) — regionale Filterung durch den BBK-Server; bevorzugt wenn AGS-Codes konfiguriert
2. **mapData-Endpunkt** (`/{quelle}/mapData.json`) — bundesweit, nur aktiv wenn **keine** AGS-Codes konfiguriert
- **De-Duplikation:** ID-Normalisierung verhindert Doppelmeldungen (`dwdmap.` → `dwd.`, `mow.``mowas.` usw.)
- **Schweregrade:** Minor / Moderate / Severe (Standard) / Extreme
- **Quellen:** Katwarn, BIWAPP, MoWaS, DWD, LHP, Polizei (einzeln aktivierbar)
- **Monitor-Modus:** `send_to_mesh=false` → Weboberfläche empfängt Warnungen, kein Funk-Versand
- **Resend-Loop:** Aktive Warnungen werden in konfigurierbarem Abstand erneut gesendet
- **Hot-Reload:** Konfigurationsänderungen in `nina.yaml` werden live übernommen
- **AGS-Unterstützung:** Alle 13 sächsischen Landkreise / kreisfreie Städte mit lesbaren Namen
**Mesh-Nachrichtenformat:**
```
[NINA] Schwerwiegend: Sturmböen (Dresden, Stadt)
Beschreibung des Ereignisses (max. 120 Zeichen)...
[NINA] Aufgehoben: Sturmböen (Dresden, Stadt)
```
### `meshbot/scheduler.py` — Scheduler
Zeitgesteuerte Bot-Aktionen via Cron-Ausdrücke:
- **Cron-Parser:** eigene Implementierung (keine externen Abhängigkeiten)
- Format: `Minute Stunde Tag Monat Wochentag`
- Unterstützt `*`, `*/N`, Einzelwerte und Kommalisten
- **Job-Typen:** `command` (Bot-Kommando) oder `message` (freier Text)
- **Template-Variablen** für Nachrichten-Jobs:
- `{time}`, `{date}`, `{datetime}`, `{weekday}`
- `{nodes}`, `{nodes_24h}` (live aus der DB)
- **Hot-Reload:** Änderungen in `scheduler.yaml` werden alle 2 Sekunden erkannt
- **CRUD-API:** Jobs können über die Weboberfläche angelegt, bearbeitet und gelöscht werden
### `meshbot/webserver.py` — WebServer
aiohttp-basierter HTTP- und WebSocket-Server:
- **WebSocketManager:** trennt `clients` (alle) von `auth_clients` (authentifiziert)
- **Initial-Payload bei WS-Verbindung:** Nodes, Stats, Channels, my_node_id, Bot-Status, letzte 200 Pakete, letzte 50 Nachrichten (nur auth)
- **broadcast vs. broadcast_auth:** Nachrichten und Warnmeldungen nur an authentifizierte Clients
### `meshbot/auth.py` — Authentifizierung
Session-basierte Authentifizierung mit E-Mail-Verifikation:
- **Passwort-Hashing:** bcrypt, 12 Runden, Mindestlänge 8 Zeichen
- **Session-Storage:** `EncryptedCookieStorage` (Fernet, AES-128-CBC)
- **Token-System:** UUID-Tokens für Verifikation und Passwort-Reset (24h gültig)
- **E-Mail-Versand:** aiosmtplib (TLS Port 465), Fallback: Link ins Server-Log
- **Rollen:** `public` (nicht eingeloggt), `user`, `admin`
- **Admin kann:** Benutzer anlegen/bearbeiten/löschen, Rollen ändern, manuell verifizieren, Passwörter zurücksetzen, Info-Mails versenden
### `meshbot/database.py` — Datenbank
SQLite via aiosqlite mit WAL-Modus für bessere Nebenläufigkeit:
| Tabelle | Inhalt |
|---|---|
| `nodes` | Alle bekannten Meshtastic-Nodes (ID, Name, HW, Position, Batterie, SNR, Hops) |
| `messages` | Empfangene und gesendete Textnachrichten |
| `commands` | Bot-Kommando-Protokoll pro Kanal |
| `packets` | Alle empfangenen Pakete mit Typ und Payload |
| `users` | Registrierte Web-Benutzer |
| `tokens` | Verifikations- und Reset-Tokens |
| `email_logs` | E-Mail-Versandprotokoll |
Automatische DB-Migration bei Schema-Änderungen (z.B. `channel`-Spalte in `commands`).
### `meshbot/config.py` — Konfiguration
Live-Reload-fähige Konfiguration aus `config.yaml`:
- Datei-Watcher prüft alle 5 Sekunden auf Änderungen
- Umgebungsvariablen über `config.env()` (für Secrets wie AUTH_SECRET_KEY, SMTP)
- Verschachtelte Keys per Punkt-Notation: `config.get("meshtastic.host")`
---
## Bot-Kommandos
Alle Kommandos beginnen mit dem konfigurierten Präfix (Standard: `?`).
| Kommando | Beschreibung |
|---|---|
| `?ping` | Antwortet mit „Pong" und Hop-Anzahl des Absenders |
| `?nodes` | Anzahl bekannter Nodes im Netz |
| `?info` | Bot-Name, Version und Uptime |
| `?help` | Liste aller Kommandos |
| `?stats` | Gesamt-Nodes, aktive Nodes (24h), Anfragen-Zähler |
| `?uptime` | Laufzeit des Bots |
| `?me` | Eigene Node-Infos (Name, HW, Hops, SNR, RSSI, Batterie, Position) |
| `?weather` | Aktuelles Wetter am eigenen Standort (open-meteo.com) |
| `?weather plz:XXXXX` | Wetter für deutsche Postleitzahl |
| `?mesh` | Mesh-Netzwerk-Übersicht (Online-Nodes, Hop-Verteilung, Top-Hardware) |
Lange Antworten werden automatisch gesplittet (`[1/3] ... [2/3] ... [3/3]`).
---
## Weboberfläche & Seiten
Alle Seiten verwenden ein einheitliches Layout: Tabler 1.4.0 (Bootstrap 5.3), fixed Top-Navbar (46px), Sidebar (200px), Content-Wrapper. Theme-Toggle (Hell/Dunkel) auf allen Seiten. Sidebar-Einträge für Admin-Bereiche werden per JS ausgeblendet wenn nicht admin.
### `/` — Dashboard (public: Nodes/Stats, user: Nachrichten/Senden)
- **Info-Boxen:** Nodes gesamt, aktiv (24h), Anfragen (24h), Bot-Uptime
- **Nodes-Tabelle:** Name, ID, HW, Hops, SNR, RSSI, Batterie, Zuletzt gesehen; Suchfeld, Online-Filter, sortierbar
- **Node-Detail-Modal:** Klick auf Node-Zeile öffnet Modal mit allen Feldern + Leaflet-Minikarte
- **Kanalfilter** in der Nachrichtenliste
- **Sende-Card** (user): Kanal-Dropdown + Textfeld → `POST /api/send`
- **Charts** (3 + 1):
- Kanal-Anfragen (Doughnut)
- Hop-Verteilung (Bar)
- Hardware Top-5 (Bar)
- Pakettypen 24h (Doughnut)
### `/map` — Karte (public)
- Leaflet.js mit Node-Markierungen
- **Farb-Codierung nach Hop-Anzahl:** Direkt=Grün, 1 Hop=Blau, 2 Hops=Orange, ≥3 Hops=Rot, via MQTT=Lila
- **Transparenz nach Alter:** <24h=90%, 2448h=45%, 4872h=20%, >72h=ausgeblendet
- **Kartenlegende** (topleft): Theme-aware, kompaktes Design mit HOPS- und ALTER-Sektionen
- **Dark/Light Tiles:** CartoDB Dark Matter / OpenStreetMap, wechselt live mit Theme
- **Tooltip** mit Node-Name, HW, Hops, Batterie, SNR beim Hover
### `/packets` — Paket-Log (public)
- Echtzeit-Tabelle aller empfangenen Pakete (max. 300 Einträge im Browser)
- Spalten: Zeit, Von, An, Typ, Kanal, SNR, RSSI, Hops, Info
- **Typ-Filterleiste** (farbige Pills, aktiv/inaktiv)
- **Pause- und Löschen-Funktion**
- Eigene Telemetrie-Pakete werden unterdrückt (`my_node_id` oder FTLW-Fallback)
- Informativer Info-Payload je Pakettyp
### `/scheduler` — Scheduler (admin)
- Jobs-Tabelle: Name, Cron-Ausdruck, Typ, Kommando/Nachricht, Kanal, Aktiv
- CRUD-Modals für Anlegen/Bearbeiten/Löschen
- Variablen-Badges (`{time}`, `{date}`, ...) klickbar im Nachrichten-Modus
### `/nina` — NINA-Warnmeldungen (admin)
- **Konfigurationskarte** mit allen NINA-Einstellungen (aktiviert, Send-to-Mesh, Intervalle, Kanal, Schweregrad, AGS-Codes, Quellen)
- **AGS-Code-Tabelle** mit Ortsname und Lösch-Button; Combobox mit allen sächsischen AGS-Codes
- **Status-Badge** (Aktiv/Deaktiviert, Regions-Anzahl, Mesh+Web/Nur Web)
- **Warnmeldungs-Tabelle:** Schweregrad-Badge, Headline, Gebiet, Typ, Mesh-Icon, Zeitstempel
- Aktive Warnungen werden beim Seitenaufruf sofort geladen (`GET /api/nina/alerts`)
- Neue Warnungen erscheinen live via WebSocket
### `/settings` — Node-Einstellungen (admin)
- Liest aktuelle Konfiguration vom lokalen Meshtastic-Node
- Zeigt: Gerät (Name, Firmware, HW-Modell, Node-Num), LoRa (Region, Preset, Hops, TX-Power), Kanäle, Position, Power, Bluetooth, Netzwerk
### `/admin` — Benutzerverwaltung (admin)
- Benutzertabelle mit Rolle, Verifikationsstatus, Erstellt-Datum
- Aktionen: Anlegen, Bearbeiten, Rolle ändern, Passwort zurücksetzen, verifizieren, löschen, Info-Mail senden
- Passwort-Generator in der UI
### `/login` + `/register` — Authentifizierung (public)
- Login / Registrierung / Passwort vergessen auf einer Seite
- E-Mail-Verifikationsflow: Token → Passwort setzen → Login
- Passwort-Reset-Flow analog
---
## REST-API-Referenz
### Öffentliche Endpunkte
| Methode | Pfad | Beschreibung |
|---|---|---|
| `GET` | `/api/nodes` | Alle Nodes |
| `GET` | `/api/stats` | Statistiken + Version + Uptime |
| `GET` | `/api/packets` | Letzte Pakete (limit-Parameter) |
| `GET` | `/ws` | WebSocket-Verbindung |
### User-Endpunkte
| Methode | Pfad | Beschreibung |
|---|---|---|
| `GET` | `/api/auth/me` | Eigene Benutzerdaten |
| `GET` | `/api/messages` | Letzte Nachrichten |
| `POST` | `/api/send` | Nachricht senden |
### Admin-Endpunkte
| Methode | Pfad | Beschreibung |
|---|---|---|
| `GET` | `/api/node/config` | Node-Konfiguration lesen |
| `GET/POST` | `/api/scheduler/jobs` | Jobs lesen / anlegen |
| `PUT/DELETE` | `/api/scheduler/jobs/{name}` | Job bearbeiten / löschen |
| `GET` | `/api/nina/config` | NINA-Konfiguration lesen |
| `PUT` | `/api/nina/config` | NINA-Konfiguration speichern + Poll auslösen |
| `GET` | `/api/nina/alerts` | Aktuell aktive Warnmeldungen |
| `GET/POST` | `/api/admin/users` | Alle Benutzer / Anlegen |
| `PUT` | `/api/admin/users/{id}` | Benutzer bearbeiten |
| `DELETE` | `/api/admin/users/{id}` | Benutzer löschen |
| `POST` | `/api/admin/users/{id}/role` | Rolle ändern |
| `POST` | `/api/admin/users/{id}/verify` | Manuell verifizieren |
| `POST` | `/api/admin/users/{id}/reset-password` | Passwort zurücksetzen |
| `POST` | `/api/admin/users/{id}/send-info` | Info-Mail senden |
### Auth-Endpunkte
| Methode | Pfad | Beschreibung |
|---|---|---|
| `POST` | `/auth/login` | Einloggen |
| `POST` | `/auth/register` | Registrieren |
| `GET` | `/auth/logout` | Ausloggen |
| `GET` | `/auth/verify` | Verifikations-Link |
| `POST` | `/auth/set-password` | Passwort nach Verifikation setzen |
| `POST` | `/auth/forgot-password` | Passwort-Reset anfordern |
| `GET/POST` | `/auth/reset-password` | Passwort zurücksetzen |
### WebSocket-Events (Server → Client)
| Event | Inhalt | Auth |
|---|---|---|
| `initial` | Alle Nodes | alle |
| `stats_update` | Statistiken | alle |
| `channels` | Kanäle | alle |
| `my_node_id` | Eigene Node-ID | alle |
| `bot_status` | connected + uptime | alle |
| `initial_packets` | Letzte 200 Pakete | alle |
| `node_update` | Node-Daten (ein Node) | alle |
| `packet` | Neues Paket | alle |
| `initial_messages` | Letzte 50 Nachrichten | auth |
| `new_message` | Neue Nachricht | auth |
| `scheduler_update` | Jobs-Liste | alle |
| `nina_alert` | Neue Warnmeldung | alle |
---
## Zugriffsrechte
| Bereich | Public | User | Admin |
|---|---|---|---|
| Dashboard (Nodes, Stats, Karte) | Ja | Ja | Ja |
| Paket-Log | Ja | Ja | Ja |
| Dashboard (Nachrichten, Senden) | Nein | Ja | Ja |
| Scheduler | Nein | Nein | Ja |
| NINA-Verwaltung | Nein | Nein | Ja |
| Node-Einstellungen | Nein | Nein | Ja |
| Benutzerverwaltung | Nein | Nein | Ja |
---
## Konfiguration
### `config.yaml` — Hauptkonfiguration
```yaml
version: "0.08.09"
bot:
name: "MeshDD-Bot"
command_prefix: "?" # Präfix für Bot-Kommandos
meshtastic:
host: "192.168.11.4" # IP des Meshtastic-Nodes
port: 4403 # TCP-Port
web:
host: "0.0.0.0" # Web-Server-Bindung
port: 8081 # Web-Server-Port
database:
path: "meshdd.db" # Pfad zur SQLite-DB
auth:
session_max_age: 86400 # Session-Gültigkeit in Sekunden
```
### `.env` — Secrets (Umgebungsvariablen)
```
AUTH_SECRET_KEY=change-this-secret-key-32bytes!!
SMTP_HOST=ssl0.example.com
SMTP_PORT=465
SMTP_USER=bot@example.com
SMTP_PASSWORD=secret
SMTP_FROM=MeshDD-Bot <bot@example.com>
SMTP_APP_URL=http://192.168.11.x:8081
```
Ohne `SMTP_HOST` werden Verifikationslinks ins Server-Log ausgegeben (kein E-Mail-Versand).
### `scheduler.yaml` — Scheduler-Jobs
```yaml
jobs:
- name: "tagesinfo"
enabled: true
cron: "0 8 * * *" # täglich 08:00
type: "message"
command: "Guten Morgen! Heute {weekday}, {date}. Aktive Nodes: {nodes_24h}"
channel: 0
- name: "morgen-ping"
enabled: false
cron: "0 7 * * 1-5" # MoFr 07:00
type: "command"
command: "?ping"
channel: 0
```
**Cron-Felder:** `Minute(0-59) Stunde(0-23) Tag(1-31) Monat(1-12) Wochentag(0-6, 0=Sonntag)`
**Template-Variablen:** `{time}` `{date}` `{datetime}` `{weekday}` `{nodes}` `{nodes_24h}`
### `nina.yaml` — NINA-Konfiguration
```yaml
enabled: false
send_to_mesh: true
poll_interval: 300 # Abfrageintervall in Sekunden (min. 60)
resend_interval: 3600 # Wiederholungsintervall aktiver Warnungen
channel: 0 # Meshtastic-Kanal 07
min_severity: Severe # Minor | Moderate | Severe | Extreme
ags_codes:
- "146120000000" # Dresden, Stadt
- "146270000000" # Meißen
- "146280000000" # Sächsische Schweiz-Osterzgebirge
- "146250000000" # Bautzen
- "146260000000" # Görlitz
sources:
katwarn: true
biwapp: true
mowas: true
dwd: true
lhp: true
police: false
```
---
## Datenbank
SQLite-Datei `meshdd.db` (konfigurierbar). WAL-Modus für bessere Nebenläufigkeit.
### Tabelle `nodes`
```sql
node_id TEXT PRIMARY KEY, -- z.B. "!1a2b3c4d"
node_num INTEGER, -- Dezimalzahl
long_name TEXT, -- Langer Name
short_name TEXT, -- Kurzname (4 Zeichen)
hw_model TEXT, -- Hardware-Modell
lat REAL, lon REAL, -- Position
alt REAL, -- Höhe in Metern
battery INTEGER, -- Akkustand 0100%
voltage REAL, -- Spannung in Volt
snr REAL, -- Signal-Rausch-Abstand
rssi INTEGER, -- Empfangsstärke in dBm
last_seen REAL, -- Unix-Timestamp
first_seen REAL, -- Unix-Timestamp
hop_count INTEGER, -- Hops vom Bot
via_mqtt INTEGER -- 0 oder 1
```
### Tabelle `packets`
```sql
id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp REAL,
from_id TEXT, to_id TEXT,
portnum TEXT, -- z.B. "TEXT_MESSAGE_APP"
channel INTEGER,
snr REAL, rssi INTEGER,
hop_limit INTEGER, hop_start INTEGER,
packet_id INTEGER,
payload TEXT -- JSON-Zusammenfassung je Typ
```
---
## Deployment
### Systemd-Service
```bash
# Service-Datei installieren
sudo cp meshdd-bot.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable meshdd-bot
sudo systemctl start meshdd-bot
# Logs live verfolgen
journalctl -u meshdd-bot -f
```
### Direkt (Entwicklung)
```bash
cd /home/peter/MeshDD-Bot
source venv/bin/activate
python main.py
```
---
## Wichtige Erweiterungsschritte
Die folgende Tabelle zeigt die wichtigsten Entwicklungsmeilensteine von der ersten Version bis heute:
| Version | Datum | Erweiterungsschritt |
|---|---|---|
| **0.01.00** | 2026-02-15 | **Grundgerüst:** Meshtastic TCP-Bot, SQLite-DB, Web-Dashboard mit WebSocket, Leaflet-Karte, Bot-Kommandos (ping, nodes, info, help, weather, stats, uptime) |
| **0.02.00** | 2026-02-15 | **Konfiguration & Karte:** Zentrale `config.yaml` mit Live-Reload, Hop-Farbcodierung auf der Karte, Theme-Toggle (Hell/Dunkel), Kanalnamen in Nachrichten |
| **0.02.05** | 2026-02-15 | **Nachrichten-Splitting:** Automatisches Aufteilen langer Nachrichten mit `[x/y]`-Nummerierung und Pause |
| **0.03.01** | 2026-02-15 | **Scheduler:** Zeitgesteuerte Bot-Kommandos via Cron-Ausdrücke, `scheduler.yaml` mit File-Watcher, REST-CRUD-API, Live-Updates via WebSocket |
| **0.03.02** | 2026-02-15 | **Nachrichten senden:** Direktes Senden aus dem Dashboard (`POST /api/send`); Scheduler-Typ „Nachricht" |
| **0.03.05** | 2026-02-15 | **AdminLTE-Layout:** Einheitliches Sidebar-Layout für alle Seiten mit Active-State |
| **0.03.06** | 2026-02-15 | **Node-Einstellungen:** `/settings`-Seite liest Gerät, LoRa, Kanäle, Position, Power, Bluetooth via Protobuf vom Node |
| **0.04.00** | 2026-02-16 | **UX-Verbesserungen:** `?me`-Kommando, Ping mit Hop-Anzahl, PLZ-Support fürs Wetter, Luftdruck & Taupunkt, gesendete Nachrichten im Dashboard |
| **0.05.00** | 2026-02-16 | **Benutzerverwaltung:** Session-Auth mit bcrypt, E-Mail-Verifikation, Rollen (public/user/admin), Admin-Panel, Passwort-Reset |
| **0.05.03** | 2026-02-16 | **Secrets in .env:** AUTH_SECRET_KEY und SMTP-Einstellungen aus config.yaml in Umgebungsvariablen ausgelagert |
| **0.05.04** | 2026-02-16 | **Admin erweitert:** Benutzer direkt anlegen mit Passwort, Bearbeiten-Modal, Passwort-Reset, Passwort-Generator |
| **0.06.00** | 2026-02-17 | **Node-Detail-Modal:** Klick auf Node → Modal mit allen Feldern + Leaflet-Minikarte |
| **0.06.02** | 2026-02-17 | **Geteiltes app.js:** ~360 Zeilen duplizierten Frontend-Code in gemeinsames Modul extrahiert |
| **0.06.03** | 2026-02-17 | **WebSocket-Sicherheit:** `auth_clients` vs. `clients` — Nachrichten nur an authentifizierte WS-Clients |
| **0.06.05** | 2026-02-17 | **Dark-Mode-Karte + Charts:** CartoDB Dark Matter, 3 Charts (Kanal, Hops, Hardware) |
| **0.06.07** | 2026-02-17 | **Tabler 1.4.0:** Professionelleres CSS-Framework, überarbeitetes style.css |
| **0.06.10** | 2026-02-18 | **Paket-Log:** Neue `/packets`-Seite, `packets`-Tabelle in DB, Typ-Filter, Echtzeit via WebSocket |
| **0.06.13** | 2026-02-18 | **Karten-Alter-Transparenz:** Nodes >72h werden ausgeblendet; Legende mit Alter-Sektion |
| **0.06.14** | 2026-02-18 | **Pakettypen-Chart:** Viertes Doughnut-Chart mit Pakettyp-Verteilung 24h |
| **0.06.15** | 2026-02-18 | **Scheduler Template-Variablen:** `{time}`, `{date}`, `{weekday}`, `{nodes}` etc.; Footer auf allen Seiten |
| **0.08.00** | 2026-02-19 | **NINA-Integration:** BBK Warn-App angebunden; duales Polling (Dashboard + mapData); Konfigurationsseite; Monitor-Modus; Live-Tabelle via WebSocket |
| **0.08.01** | 2026-02-19 | **NINA Resend-Loop:** Aktive Warnungen werden zyklisch wiederholt; AGS-Code-Tabelle statt Badges |
| **0.08.02** | 2026-02-19 | **NINA geografische Filterung:** mapData nur noch ohne AGS-Codes aktiv (verhindert bundesweite Meldungen) |
| **0.08.03** | 2026-02-19 | **NINA Gebietsanzeige:** Regionsname aus AGS-Labels in Meldung und Mesh-Text; Sachsen-Combobox |
| **0.08.04** | 2026-02-19 | **NINA Sofortabfrage:** Nach Speichern der Config sofort pollen; `last_poll`-Zeitstempel anzeigen |
| **0.08.05** | 2026-02-19 | **Kartenlegende Position:** von bottomright nach topleft verschoben |
| **0.08.06** | 2026-02-19 | **Paket-Log informativer:** Erweiterte Payload-Zusammenfassung; eigene Telemetrie unterdrückt |
| **0.08.07** | 2026-02-19 | **Race-Condition-Fix:** `threading.Event` verhindert falsche Startup-Warning „connection.established missed" |
| **0.08.08** | 2026-02-19 | **Kartenlegende neu gestaltet:** Theme-aware CSS-Variablen, kompaktes Design |
| **0.08.09** | 2026-02-19 | **NINA aktive Warnungen:** `GET /api/nina/alerts` gibt beim Seitenaufruf alle aktiven Warnungen zurück |
---
*MeshDD-Bot — entwickelt für das Dresdner Meshtastic-Netz · © MeshDD / PPfeiffer*