Inhaltsverzeichnis
Kapitel 4 – Lektion 8.2: Asynchrone Sensoranzeige mit Live-Updates
In Lektion 8 haben wir die Sensorwerte über eine normale URL angezeigt. Das funktioniert – aber es hat einen Nachteil:
Wenn du neue Werte sehen willst, musst du die Seite neu laden (oder per Meta-Refresh aktualisieren).
In dieser Lektion machen wir es moderner: Die Webseite bleibt offen und holt sich die Messwerte asynchron im Hintergrund nach.
Das ist ein wichtiger Schritt Richtung „echte Web-App“:
- Seite wird einmal geladen
- Daten kommen später nach (ohne Reload)
Ziel dieser Lektion
Am Ende hast du:
- eine Route `/api/sensor`, die Werte als JSON liefert
- eine Webseite, die diese JSON-Daten per JavaScript regelmäßig abruft
- ein Live-Dashboard für Temperatur und Luftfeuchtigkeit
Was bedeutet „asynchron“ hier?
Asynchron heißt in dieser Lektion ganz praktisch:
- Der Pico liefert Daten über eine kleine API-URL (`/api/sensor`)
- Die Webseite ruft diese Daten alle paar Sekunden ab
- Die Seite selbst wird dabei nicht neu geladen
Wir nutzen dafür kein großes Framework, sondern nur:
- JSON als Datenformat
- `fetch()` im Browser
Schritt 1: API-Route in webserver.py ergänzen
Erweitere deine `webserver.py` um eine neue Route:
- `/api/sensor`
Diese Route gibt die aktuellen Werte als JSON zurück.
Füge in `webserver.py` diese Funktion hinzu:
def _sensor_api(httpClient, httpResponse): try: temp, hum = _read_dht_cached(2) # JSON-String (ohne extra Bibliotheken) json_str = '{"temp": %d, "hum": %d}' % (temp, hum) httpResponse.WriteResponseOk( headers=None, contentType="application/json", contentCharset="UTF-8", content=json_str ) except Exception as e: httpResponse.WriteResponseOk( headers=None, contentType="application/json", contentCharset="UTF-8", content='{"error": "sensor"}' )
Und ergänze die Route in deiner `start_webserver()`:
routes = [ ("/sensor", "GET", _sensor_page), ("/api/sensor", "GET", _sensor_api), ]
Schritt 2: Live-Anzeige in index.html einbauen
Jetzt bauen wir auf der Startseite eine Card, die Werte live aktualisiert.
Öffne `/www/index.html` und füge (z. B. unter deinen bisherigen Cards/Buttons) Folgendes ein:
<div class="card shadow-sm mt-4"> <div class="card-body"> <h5 class="card-title">Live Sensorwerte</h5> <p class="mb-1">Temperatur: <strong><span id="temp">--</span> °C</strong></p> <p class="mb-0">Luftfeuchtigkeit: <strong><span id="hum">--</span> %</strong></p> <small class="text-muted d-block mt-2"> Aktualisierung alle 2 Sekunden – ohne Seiten-Reload </small> </div> </div> <script> async function loadSensor() { try { const res = await fetch('/api/sensor'); const data = await res.json(); if (data.error) { document.getElementById('temp').textContent = 'Fehler'; document.getElementById('hum').textContent = 'Fehler'; return; } document.getElementById('temp').textContent = data.temp; document.getElementById('hum').textContent = data.hum; } catch (e) { document.getElementById('temp').textContent = '---'; document.getElementById('hum').textContent = '---'; } } loadSensor(); setInterval(loadSensor, 2000); </script>
Jetzt aktualisiert sich die Anzeige alle 2 Sekunden automatisch.
Schritt 3: Test
- Starte `main.py`
- Öffne
http://<IP-DEINES-PICO>/
- Beobachte die Card „Live Sensorwerte“
Du wirst sehen: Die Werte aktualisieren sich automatisch – ohne Reload.
Warum das für IoT wichtig ist
Stell dir später vor:
- du steuerst LEDs / Relais
- du liest Sensoren aus
- du willst gleichzeitig ein Dashboard anzeigen
Wenn du immer komplette Seiten neu laden musst, wirkt das „alt“ und belastet den Pico unnötig.
Mit diesem Ansatz:
- bleibt die Oberfläche stabil offen
- du holst nur kleine Datenpakete (JSON)
- und dein Projekt fühlt sich sofort wie eine echte Web-App an
Übung
- Passe das Intervall an (z. B. 5 Sekunden)
- Zeige Fahrenheit zusätzlich an:
- `F = temp * 9 / 5 + 32`
- Gib bei Fehlern eine Bootstrap-Alert-Box aus (statt nur Text)
Ausblick
Im nächsten Schritt nutzen wir genau diese Technik auch für:
- Live-Status von GPIOs
- Buttons ohne Seitenwechsel
- (optional) WebSockets – wenn du richtig „Realtime“ willst
