docs: vollständige Bot-Beschreibung und 0.8.x Release-Notes hinzugefügt
- docs/bot-beschreibung.md: umfassende Dokumentation mit Architektur, Komponenten, API-Referenz, Konfiguration, Datenbank-Schema, Deployment und chronologischer Erweiterungshistorie (v0.1.0–v0.8.9) - docs/whats-new-0.8.md: Neuigkeiten der 0.8.x-Release-Serie (NINA, Paket-Log, Karte, Bugfixes, API-Endpunkte, Versionshistorie) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
f36a126200
commit
79f80563c8
597
docs/bot-beschreibung.md
Normal file
597
docs/bot-beschreibung.md
Normal file
|
|
@ -0,0 +1,597 @@
|
|||
# MeshDD-Bot — Vollständige Beschreibung
|
||||
|
||||
> Aktueller Stand: **v0.8.9** · 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
|
||||
- Docker-ready mit docker-compose
|
||||
|
||||
---
|
||||
|
||||
## 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 / Docker + docker-compose |
|
||||
|
||||
---
|
||||
|
||||
## 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%, 24–48h=45%, 48–72h=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.8.9"
|
||||
|
||||
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" # Mo–Fr 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 0–7
|
||||
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 0–100%
|
||||
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
|
||||
```
|
||||
|
||||
### Docker / docker-compose
|
||||
|
||||
```bash
|
||||
# Bauen und starten
|
||||
docker compose up -d
|
||||
|
||||
# Logs
|
||||
docker compose logs -f
|
||||
|
||||
# Stoppen
|
||||
docker compose down
|
||||
```
|
||||
|
||||
`docker-compose.yml` verwendet Host-Netzwerk (direkter TCP-Zugriff auf Meshtastic-Node), Named Volume für SQLite, JSON-File-Logging (10 MB / 3 Dateien) und Health-Check (`/api/stats` alle 30s).
|
||||
|
||||
### 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.1.0** | 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.2.0** | 2026-02-15 | **Konfiguration & Karte:** Zentrale `config.yaml` mit Live-Reload, Hop-Farbcodierung auf der Karte, Theme-Toggle (Hell/Dunkel), Kanalnamen in Nachrichten |
|
||||
| **0.2.5** | 2026-02-15 | **Nachrichten-Splitting:** Automatisches Aufteilen langer Nachrichten mit `[x/y]`-Nummerierung und Pause |
|
||||
| **0.3.1** | 2026-02-15 | **Scheduler:** Zeitgesteuerte Bot-Kommandos via Cron-Ausdrücke, `scheduler.yaml` mit File-Watcher, REST-CRUD-API, Live-Updates via WebSocket |
|
||||
| **0.3.2** | 2026-02-15 | **Nachrichten senden:** Direktes Senden aus dem Dashboard (`POST /api/send`); Scheduler-Typ „Nachricht" |
|
||||
| **0.3.5** | 2026-02-15 | **AdminLTE-Layout:** Einheitliches Sidebar-Layout für alle Seiten mit Active-State |
|
||||
| **0.3.6** | 2026-02-15 | **Node-Einstellungen:** `/settings`-Seite liest Gerät, LoRa, Kanäle, Position, Power, Bluetooth via Protobuf vom Node |
|
||||
| **0.4.0** | 2026-02-16 | **UX-Verbesserungen:** `?me`-Kommando, Ping mit Hop-Anzahl, PLZ-Support fürs Wetter, Luftdruck & Taupunkt, gesendete Nachrichten im Dashboard |
|
||||
| **0.5.0** | 2026-02-16 | **Benutzerverwaltung:** Session-Auth mit bcrypt, E-Mail-Verifikation, Rollen (public/user/admin), Admin-Panel, Passwort-Reset |
|
||||
| **0.5.3** | 2026-02-16 | **Secrets in .env:** AUTH_SECRET_KEY und SMTP-Einstellungen aus config.yaml in Umgebungsvariablen ausgelagert |
|
||||
| **0.5.4** | 2026-02-16 | **Admin erweitert:** Benutzer direkt anlegen mit Passwort, Bearbeiten-Modal, Passwort-Reset, Passwort-Generator |
|
||||
| **0.6.0** | 2026-02-17 | **Node-Detail-Modal:** Klick auf Node → Modal mit allen Feldern + Leaflet-Minikarte |
|
||||
| **0.6.1** | 2026-02-17 | **Docker-Support:** Dockerfile, docker-compose.yml, .dockerignore |
|
||||
| **0.6.2** | 2026-02-17 | **Geteiltes app.js:** ~360 Zeilen duplizierten Frontend-Code in gemeinsames Modul extrahiert |
|
||||
| **0.6.3** | 2026-02-17 | **WebSocket-Sicherheit:** `auth_clients` vs. `clients` — Nachrichten nur an authentifizierte WS-Clients |
|
||||
| **0.6.5** | 2026-02-17 | **Dark-Mode-Karte + Charts:** CartoDB Dark Matter, 3 Charts (Kanal, Hops, Hardware) |
|
||||
| **0.6.7** | 2026-02-17 | **Tabler 1.4.0:** Professionelleres CSS-Framework, überarbeitetes style.css |
|
||||
| **0.6.10** | 2026-02-18 | **Paket-Log:** Neue `/packets`-Seite, `packets`-Tabelle in DB, Typ-Filter, Echtzeit via WebSocket |
|
||||
| **0.6.13** | 2026-02-18 | **Karten-Alter-Transparenz:** Nodes >72h werden ausgeblendet; Legende mit Alter-Sektion |
|
||||
| **0.6.14** | 2026-02-18 | **Pakettypen-Chart:** Viertes Doughnut-Chart mit Pakettyp-Verteilung 24h |
|
||||
| **0.6.15** | 2026-02-18 | **Scheduler Template-Variablen:** `{time}`, `{date}`, `{weekday}`, `{nodes}` etc.; Footer auf allen Seiten |
|
||||
| **0.7.0** | 2026-02-18 | **Docker-Verbesserungen:** HEALTHCHECK, Logging-Config, korrigierter Port |
|
||||
| **0.8.0** | 2026-02-19 | **NINA-Integration:** BBK Warn-App angebunden; duales Polling (Dashboard + mapData); Konfigurationsseite; Monitor-Modus; Live-Tabelle via WebSocket |
|
||||
| **0.8.1** | 2026-02-19 | **NINA Resend-Loop:** Aktive Warnungen werden zyklisch wiederholt; AGS-Code-Tabelle statt Badges |
|
||||
| **0.8.2** | 2026-02-19 | **NINA geografische Filterung:** mapData nur noch ohne AGS-Codes aktiv (verhindert bundesweite Meldungen) |
|
||||
| **0.8.3** | 2026-02-19 | **NINA Gebietsanzeige:** Regionsname aus AGS-Labels in Meldung und Mesh-Text; Sachsen-Combobox |
|
||||
| **0.8.4** | 2026-02-19 | **NINA Sofortabfrage:** Nach Speichern der Config sofort pollen; `last_poll`-Zeitstempel anzeigen |
|
||||
| **0.8.5** | 2026-02-19 | **Kartenlegende Position:** von bottomright nach topleft verschoben |
|
||||
| **0.8.6** | 2026-02-19 | **Paket-Log informativer:** Erweiterte Payload-Zusammenfassung; eigene Telemetrie unterdrückt |
|
||||
| **0.8.7** | 2026-02-19 | **Race-Condition-Fix:** `threading.Event` verhindert falsche Startup-Warning „connection.established missed" |
|
||||
| **0.8.8** | 2026-02-19 | **Kartenlegende neu gestaltet:** Theme-aware CSS-Variablen, kompaktes Design |
|
||||
| **0.8.9** | 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*
|
||||
205
docs/whats-new-0.8.md
Normal file
205
docs/whats-new-0.8.md
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
# Was ist neu in MeshDD-Bot 0.8.x
|
||||
|
||||
> Aktueller Stand: **v0.8.9** · Release-Datum: 2026-02-19
|
||||
|
||||
---
|
||||
|
||||
## Übersicht
|
||||
|
||||
Release 0.8 bringt die vollständige Integration des **NINA BBK Warnsystems** in den
|
||||
MeshDD-Bot, ergänzt um eine Reihe von Verbesserungen am Paket-Log, der Karte und der
|
||||
Verbindungsinitialisierung.
|
||||
|
||||
---
|
||||
|
||||
## Neue Funktionen
|
||||
|
||||
### NINA Warnmeldungs-Integration (`/nina`)
|
||||
|
||||
Der Bot ist jetzt an die **NINA Warn-App des BBK** (Bundesamt für Bevölkerungsschutz
|
||||
und Katastrophenhilfe) angebunden. Warnmeldungen werden automatisch per HTTP-Polling
|
||||
von `warnung.bund.de/api31` abgerufen und ins Meshtastic-Netz gesendet.
|
||||
|
||||
#### Konfigurationsseite
|
||||
|
||||
Unter `/nina` (Admin-only) steht eine vollständige Verwaltungsseite bereit:
|
||||
|
||||
| Einstellung | Beschreibung |
|
||||
|---|---|
|
||||
| **Aktiviert** | NINA-Abfragen ein-/ausschalten |
|
||||
| **Ins Mesh senden** | Aus = Monitor-Modus (nur Weboberfläche, kein Mesh-Versand) |
|
||||
| **Abfrageintervall** | Wie oft neue Warnmeldungen abgerufen werden (Sek., min. 60) |
|
||||
| **Wiederholungsintervall** | Aktive Warnungen werden in diesem Abstand erneut ins Mesh gesendet |
|
||||
| **Kanal** | Meshtastic-Kanal (0–7) für den Versand |
|
||||
| **Mindest-Schweregrad** | Gering / Mäßig / Schwerwiegend / Extrem |
|
||||
| **AGS-Codes** | Amtliche Gemeindeschlüssel der zu überwachenden Regionen |
|
||||
| **Quellen** | Katwarn, BIWAPP, MoWaS, DWD, LHP, Polizei |
|
||||
|
||||
#### AGS-Code-Verwaltung
|
||||
|
||||
- AGS-Codes werden in einer **Tabelle** mit Ortsname und Lösch-Button angezeigt
|
||||
- Bei der Eingabe schlägt eine **Combobox** alle sächsischen Landkreise und kreisfreien
|
||||
Städte vor (Name + 12-stelliger Code)
|
||||
- Voreingestellt: 5 Codes für den **Raum Dresden** (Stadt Dresden, LK Meißen,
|
||||
LK Sächsische Schweiz-Osterzgebirge, LK Bautzen, LK Görlitz)
|
||||
|
||||
#### Polling-Strategie
|
||||
|
||||
Zwei parallele Abfragestrategien pro Zyklus:
|
||||
|
||||
1. **Dashboard-Endpunkt** (`/dashboard/{AGS12}.json`) — regionale Filterung durch den
|
||||
BBK-Server; deckt alle Quellen für konfigurierte AGS-Codes ab.
|
||||
2. **mapData-Endpunkt** (`/{quelle}/mapData.json`) — wird **nur verwendet, wenn keine
|
||||
AGS-Codes konfiguriert sind** (bundesweite Abfrage ohne Geo-Filterung).
|
||||
|
||||
Quellenübergreifende **De-Duplikation** via ID-Normalisierung verhindert doppelte
|
||||
Meldungen (z. B. `dwdmap.` ↔ `dwd.`, `mow.` ↔ `mowas.`).
|
||||
|
||||
#### Warnmeldungen im Mesh
|
||||
|
||||
Nachrichten-Format im Meshtastic-Netz:
|
||||
|
||||
```
|
||||
[NINA] Schwerwiegend: Sturmböen (Dresden, Stadt)
|
||||
Beschreibung des Ereignisses (max. 120 Zeichen)...
|
||||
|
||||
[NINA] Aufgehoben: Sturmböen (Dresden, Stadt)
|
||||
```
|
||||
|
||||
Das **Herkunftsgebiet** (AGS-Regionsname) wird automatisch an Meldung und Aufhebung
|
||||
angehängt.
|
||||
|
||||
#### Live-Anzeige in der Weboberfläche
|
||||
|
||||
Die Tabelle „Letzte Warnmeldungen" zeigt:
|
||||
|
||||
| Spalte | Inhalt |
|
||||
|---|---|
|
||||
| **Schweregrad** | Farbiger Badge (Extrem / Schwerwiegend / Mäßig / Gering / Aufgehoben) |
|
||||
| **Meldung** | Headline der Warnung |
|
||||
| **Gebiet** | AGS-Regionsname (z. B. „Dresden, Stadt") |
|
||||
| **Typ** | Quell-Präfix (z. B. `dwd`, `katwarn`) |
|
||||
| **Mesh** | Broadcast-Icon (gesendet) oder Auge-Icon (Monitor-Only) |
|
||||
| **Zeitstempel** | Sendezeitpunkt der Warnung |
|
||||
|
||||
Beim Seitenaufruf werden alle **aktuell aktiven Warnungen** sofort geladen
|
||||
(`GET /api/nina/alerts`). Neue Warnungen erscheinen live via WebSocket.
|
||||
|
||||
#### Sofortabfrage nach dem Speichern
|
||||
|
||||
Nach dem Klick auf „Speichern" wird unmittelbar eine NINA-Abfrage gestartet — kein
|
||||
Warten auf den nächsten Intervall-Zyklus. Unterhalb des Abfrageintervall-Felds wird
|
||||
Datum und Uhrzeit der **letzten erfolgreichen Abfrage** angezeigt.
|
||||
|
||||
---
|
||||
|
||||
## Verbesserungen am Paket-Log (`/packets`)
|
||||
|
||||
### Informativerer Payload
|
||||
|
||||
Die Info-Spalte zeigt jetzt deutlich mehr Daten je Pakettyp:
|
||||
|
||||
| Typ | Angezeigte Felder |
|
||||
|---|---|
|
||||
| `POSITION_APP` | Koordinaten + Höhe (m), Geschwindigkeit (km/h), Satelliten |
|
||||
| `TELEMETRY_APP` | Akku (%), Spannung (V), Kanalauslastung (%), TX-Auslastung (%), Temperatur (°C), Luftfeuchtigkeit (%), Luftdruck (hPa) |
|
||||
| `NODEINFO_APP` | long_name, short_name, Hardware-Modell |
|
||||
| `ROUTING_APP` | Fehlercode (wenn vorhanden) |
|
||||
| `TRACEROUTE_APP` | Anzahl Hops |
|
||||
| `NEIGHBORINFO_APP` | Anzahl Nachbarn |
|
||||
|
||||
### Unterdrückung eigener Telemetrie
|
||||
|
||||
Telemetriepakete vom **eigenen Node** werden im Paket-Log weder angezeigt noch gezählt.
|
||||
Die Erkennung erfolgt automatisch per `my_node_id` (WebSocket-Initial-Payload) sowie als
|
||||
Fallback über den Short-Name `FTLW`.
|
||||
|
||||
---
|
||||
|
||||
## Verbesserungen an der Karte (`/map`)
|
||||
|
||||
### Neue Legendenposition
|
||||
|
||||
Die Kartenlegende wurde von `bottomright` nach **`topleft`** verschoben — direkt
|
||||
unterhalb der Zoom-Schaltfläche, wo sie auf allen Bildschirmgrößen sicher sichtbar ist.
|
||||
|
||||
### Neues Legengendesign
|
||||
|
||||
Die Legende wurde komplett neu gestaltet:
|
||||
|
||||
- **Theme-aware**: passt sich automatisch Light- und Dark-Mode an (CSS-Variablen)
|
||||
- **Kompaktes Layout**: kleine Uppercase-Abschnittsköpfe (`HOPS` / `ALTER`)
|
||||
- **Weicherer Schatten** und dezentes Border
|
||||
|
||||
---
|
||||
|
||||
## Bugfixes
|
||||
|
||||
### Startup-Warning „connection.established missed" (fixes #2)
|
||||
|
||||
Beim Start erschien regelmäßig eine Warnung im Log:
|
||||
|
||||
```
|
||||
[WARNING] meshbot.bot: connection.established missed – applying fallback
|
||||
```
|
||||
|
||||
**Ursache:** `bot.connect()` läuft in einem separaten Thread. Der `TCPInterface`-Konstruktor
|
||||
kehrte zurück, bevor das `connection.established`-Event aus dem Meshtastic-Bibliotheks-Thread
|
||||
gefeuert wurde. Der sofortige Check sah `_connected = False` und löste den Fallback aus.
|
||||
|
||||
**Fix:** Ein `threading.Event` (`_conn_event`) wird in `_on_connection` gesetzt.
|
||||
Nach dem Konstruktor wartet der Code bis zu 10 Sekunden auf dieses Event. Der
|
||||
Fallback greift nur noch bei echtem Ausbleiben.
|
||||
|
||||
---
|
||||
|
||||
## Konfigurationsdateien
|
||||
|
||||
### `nina.yaml`
|
||||
|
||||
Separate Hot-reload-fähige Konfigurationsdatei für NINA (analog zu `scheduler.yaml`).
|
||||
Wird automatisch angelegt wenn nicht vorhanden.
|
||||
|
||||
```yaml
|
||||
enabled: false
|
||||
send_to_mesh: true
|
||||
poll_interval: 300 # Sekunden, min. 60
|
||||
resend_interval: 3600 # Sekunden, Wiederholung aktiver Warnungen
|
||||
channel: 0 # Meshtastic-Kanal 0–7
|
||||
min_severity: Severe # Minor | Moderate | Severe | Extreme
|
||||
ags_codes: []
|
||||
sources:
|
||||
katwarn: true
|
||||
biwapp: true
|
||||
mowas: true
|
||||
dwd: true
|
||||
lhp: true
|
||||
police: false
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Neue API-Endpunkte
|
||||
|
||||
| Methode | Pfad | Beschreibung | Auth |
|
||||
|---|---|---|---|
|
||||
| `GET` | `/api/nina/config` | NINA-Konfiguration lesen | Admin |
|
||||
| `PUT` | `/api/nina/config` | NINA-Konfiguration speichern + Poll auslösen | Admin |
|
||||
| `GET` | `/api/nina/alerts` | Aktuell aktive Warnmeldungen | Admin |
|
||||
|
||||
---
|
||||
|
||||
## Versionshistorie 0.8.x
|
||||
|
||||
| Version | Datum | Schwerpunkt |
|
||||
|---|---|---|
|
||||
| 0.8.0 | 2026-02-19 | NINA-Integration (Grundfunktion) |
|
||||
| 0.8.1 | 2026-02-19 | Wiederholungsintervall, AGS-Tabelle, Badge-Fixes |
|
||||
| 0.8.2 | 2026-02-19 | mapData nur ohne AGS-Codes (geografische Filterung) |
|
||||
| 0.8.3 | 2026-02-19 | Gebietsanzeige, AGS-Ortsname, Sachsen-Combobox |
|
||||
| 0.8.4 | 2026-02-19 | Sofortabfrage nach Speichern, Zeitstempel letzte Abfrage |
|
||||
| 0.8.5 | 2026-02-19 | Kartenlegende nach topleft verschoben (fixes #5) |
|
||||
| 0.8.6 | 2026-02-19 | Informativer Paket-Payload, FTLW-Telemetrie unterdrückt (fixes #3) |
|
||||
| 0.8.7 | 2026-02-19 | threading.Event-Fix für Startup-Warning (fixes #2) |
|
||||
| 0.8.8 | 2026-02-19 | Kartenlegende neu gestaltet (theme-aware) |
|
||||
| 0.8.9 | 2026-02-19 | Aktive NINA-Warnungen beim Seitenaufruf laden |
|
||||
Loading…
Reference in a new issue