OTA-Update per MQTT
Neues Kommando <PREFIX>/cmd/ota loest ota.update() aus: laedt die Projektdateien per HTTP, erst als temporaere .ota-Dateien, und benennt sie nur bei vollem Erfolg um. Schlaegt ein Download fehl, bleiben die bisherigen Dateien unveraendert -- die Anzeige laeuft mit der alten Version weiter (Grundsatz wie beim Rest von MQTT: eine fehlgeschlagene OTA darf das Geraet nicht unbrauchbar machen). Am Gerät bestätigt, inkl. echtem Reboot: leere/ungueltige Payload, unbekanntes Kommando und nicht erreichbarer Server werden abgefangen, die Poll-Schleife laeuft unbeeinflusst weiter. Ein echtes Update mit allen Projektdateien kam sauber ueber main.py-Autostart wieder hoch. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017zTSXLK4w32PoCmFgSzp68
This commit is contained in:
@@ -66,6 +66,7 @@ beiden Startprogrammen.
|
||||
| `lx200.py` | LX200-Kommandorahmen. | ✓ |
|
||||
| `wifi.py` | WLAN-Anbindung des ESP32 (verbinden, Verbindung halten). | ✓ |
|
||||
| `mqtt.py` | MQTT: Einstellungen empfangen, Zustand veröffentlichen. | ✓ |
|
||||
| `ota.py` | OTA-Update: Dateien per HTTP laden, umbenennen, neu starten. | ✓ |
|
||||
| `run_esp32.py` | Startprogramm auf dem ESP32: WLAN, Anzeige, Schleife. | ✓ |
|
||||
| `main.py` | Autostart nach jedem Reset, mit Watchdog und Abbruchfenster. | ✓ |
|
||||
| `wifi_config.py` | WLAN-Zugangsdaten, **nicht im Git** (Vorlage `wifi_config_example.py`). | ✓ |
|
||||
@@ -548,9 +549,10 @@ Empfangen (`<PREFIX>/set/<name>`):
|
||||
| `grossanzeige/set/schwelle` | `1800` | Umschaltpunkt (LDR-Wert) |
|
||||
| `grossanzeige/set/hysterese` | `150` | Breite um den Umschaltpunkt |
|
||||
| `grossanzeige/set/mount_host` | `192.168.1.115` | Adresse der Montierung (leer = Vorgabe aus `config.py`) |
|
||||
| `grossanzeige/cmd/ota` | `http://192.168.178.50:8000` | löst ein OTA-Update aus (leer = Vorgabe aus `config.OTA_URL`, siehe [OTA-Update per MQTT](#ota-update-per-mqtt)) |
|
||||
|
||||
Alle Nutzlasten außer `mount_host` sind ganze Zahlen; `mount_host` ist Text
|
||||
(IP-Adresse oder Hostname).
|
||||
Alle Nutzlasten außer `mount_host` und `cmd/ota` sind ganze Zahlen; `mount_host`
|
||||
und `cmd/ota` sind Text (Adresse bzw. URL).
|
||||
|
||||
Gesendet (`<PREFIX>/status/<name>`, alle *retained*):
|
||||
|
||||
@@ -618,6 +620,48 @@ Der Wert geht in `socket.getaddrinfo` und kommt von außen, deshalb prüft
|
||||
`settings.py` ihn eng: nur Buchstaben, Ziffern, Punkt und Bindestrich, höchstens
|
||||
63 Zeichen. Alles andere wird verworfen, `settings.json` bleibt unberührt.
|
||||
|
||||
### OTA-Update per MQTT
|
||||
|
||||
Ein Update lässt sich anstoßen, ohne das Gerät anzustecken:
|
||||
|
||||
```bash
|
||||
cd /pfad/zum/projekt
|
||||
python3 -m http.server 8000 # einfacher Dateiserver, hier laufen lassen
|
||||
mosquitto_pub -h <broker> -t grossanzeige/cmd/ota -m http://192.168.178.50:8000
|
||||
```
|
||||
|
||||
Die Nachricht auf `<PREFIX>/cmd/ota` ist die Basis-URL des Dateiservers; eine
|
||||
leere Nachricht verwendet stattdessen `config.OTA_URL` (dieselbe Regel wie bei
|
||||
`set/mount_host` mit leerer Nachricht):
|
||||
|
||||
```bash
|
||||
mosquitto_pub -h <broker> -t grossanzeige/cmd/ota -m '' # config.OTA_URL
|
||||
```
|
||||
|
||||
`ota.py` lädt dieselben Dateien, die auch `deploy.sh` überträgt, jede zunächst
|
||||
unter einem temporären Namen (`<datei>.ota`). **Erst wenn alle Downloads
|
||||
gelingen**, werden sie auf die endgültigen Namen umbenannt und das Gerät
|
||||
startet neu (`machine.reset()`) — genau wie ein normaler Reset läuft danach
|
||||
`main.py` mit Abbruchfenster und Watchdog an. Schlägt ein einzelner Download
|
||||
fehl (Netz weg, Server nicht erreichbar, Datei fehlt), bleiben die bisherigen
|
||||
Dateien unverändert liegen, die temporären Reste werden aufgeräumt, und die
|
||||
Anzeige läuft mit der alten Version unbeeinflusst weiter — dieselbe
|
||||
Fehlerphilosophie wie beim Rest von MQTT.
|
||||
|
||||
Der Watchdog wird während des Updates weiter gefüttert (`run_esp32.make_on_ota`
|
||||
reicht den `feed` aus `main.py` durch), damit ein Update über viele Dateien
|
||||
nicht selbst einen Neustart auslöst.
|
||||
|
||||
`settings.json`, `wifi_config.py` und `mqtt_config.py` werden **nicht**
|
||||
angefasst — Laufzeitzustand bzw. Zugangsdaten, dieselbe Ausnahme wie in
|
||||
`deploy.sh`.
|
||||
|
||||
**Sicherheitshinweis:** Der Dateiserver liefert unverändert aus, was unter der
|
||||
angegebenen URL liegt — wer die MQTT-Nachricht schicken kann, bestimmt damit,
|
||||
welcher Code auf dem Gerät läuft. Das ist im Rahmen des bestehenden
|
||||
Vertrauensmodells (MQTT-Zugangsdaten in `mqtt_config.py`) beabsichtigt, aber
|
||||
kein Ersatz für einen abgesicherten Broker.
|
||||
|
||||
### Was dabei schiefgehen kann, und warum es nichts ausmacht
|
||||
|
||||
**Grundsatz: MQTT darf die Anzeige nie aufhalten.** Die Anzeige ist der Zweck des
|
||||
|
||||
Reference in New Issue
Block a user