MQTT: Einstellungen empfangen, Zustand veroeffentlichen
Topics (Praefix aus mqtt_config.py, Vorgabe "grossanzeige"):
<PREFIX>/set/hell_prozent 60 eingehend, schreibt settings.json
<PREFIX>/set/dunkel_prozent 5
<PREFIX>/set/schwelle 1800
<PREFIX>/set/hysterese 150
<PREFIX>/status/ra 18h36m56s ausgehend, retained
<PREFIX>/status/dec +38°47'01"
<PREFIX>/status/ldr 2453
<PREFIX>/status/helligkeit 50
<PREFIX>/status/link 1
<PREFIX>/status/online 1 mit Last Will auf 0
Eine empfangene Einstellung wird sofort wirksam: dieselbe Pruefung wie sonst
(settings.update), dann laedt der laufende BrightnessController sie per reload()
nach -- kein Neustart noetig.
Leitgedanke des Moduls: **MQTT darf die Anzeige nie aufhalten.** Die Anzeige ist
der Zweck des Geraets, MQTT ist Beiwerk. Deshalb faengt mqtt.py jeden Fehler
selbst ab und meldet ihn nur:
- Broker nicht erreichbar -> Versuch scheitert, Schleife laeuft weiter.
Wiederholung mit wachsendem Abstand (5..120 s), sonst kostet ein dauerhaft
toter Broker in jedem Schleifendurchlauf Zeit.
- Verbindungsabriss -> beim naechsten Senden/Empfangen bemerkt, Verbindung wird
verworfen und spaeter neu aufgebaut. Danach geht der gesamte Status erneut
raus, damit der Broker nicht auf veralteten Werten sitzenbleibt.
- Unsinniger Wert von aussen -> verworfen, settings.json bleibt unberuehrt.
- Geraet faellt aus -> Last Will meldet online=0. Ohne das bliebe online=1
stehen, obwohl niemand mehr da ist.
Der Empfang blockiert nicht (check_msg). Statuswerte gehen nur bei Aenderung
raus -- die Koordinaten aendern sich staendig, LDR und Helligkeit kaum.
mqtt_config.py ist optional und gitignored (Vorlage mqtt_config_example.py);
fehlt sie, laeuft alles wie bisher ohne MQTT. deploy.sh weist nur darauf hin.
test_mqtt.py haengt einen Fake-Broker ein und prueft auch die Faelle, die man
mit einem echten Server schwer herbeifuehrt: Abriss beim Senden, Muell im Topic,
Broker der nicht antwortet. 143 Tests gruen.
Am Geraet bestaetigt ist bisher der Fall OHNE Broker: mqtt.py importiert,
connect_from_config liefert None, ein unerreichbarer Broker wirft keine
Ausnahme. Der Test gegen einen echten Broker steht noch aus.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+20
-1
@@ -26,7 +26,8 @@ def format_coordinates(ra_raw, dec_raw):
|
||||
|
||||
|
||||
def poll_loop(display, client, interval=None, once=False,
|
||||
read_ldr=None, dimmer=None, ensure_link=None, log=None):
|
||||
read_ldr=None, dimmer=None, ensure_link=None, log=None,
|
||||
bridge=None):
|
||||
"""Zyklisch die Montierung abfragen und die Anzeige nachfuehren.
|
||||
|
||||
display offenes Display-Objekt
|
||||
@@ -40,6 +41,9 @@ def poll_loop(display, client, interval=None, once=False,
|
||||
sicherstellt (auf dem ESP32 das WLAN)
|
||||
log optional: Ausgabefunktion, Vorgabe print; None-freies Logging
|
||||
erlaubt es, auf dem ESP32 still zu laufen (log=lambda *a: None)
|
||||
bridge optional: mqtt.MqttBridge -- empfaengt Einstellungen und
|
||||
veroeffentlicht den Zustand. Faellt der Broker aus, laeuft die
|
||||
Anzeige unveraendert weiter (mqtt.py faengt seine Fehler selbst).
|
||||
|
||||
Laeuft bis KeyboardInterrupt oder -- bei once=True -- genau einmal. Fehler
|
||||
von Anzeige und Montierung werden abgefangen: die Schleife meldet sie und
|
||||
@@ -53,6 +57,11 @@ def poll_loop(display, client, interval=None, once=False,
|
||||
last_shown = None
|
||||
while True:
|
||||
try:
|
||||
# Zuerst MQTT abholen: So wirkt eine gerade gesetzte Helligkeit noch
|
||||
# in diesem Durchlauf, statt eine Runde hinterherzuhinken.
|
||||
if bridge is not None:
|
||||
bridge.check()
|
||||
|
||||
if ensure_link is not None:
|
||||
ensure_link()
|
||||
if not client.connected:
|
||||
@@ -66,6 +75,9 @@ def poll_loop(display, client, interval=None, once=False,
|
||||
display.set_brightness(percent)
|
||||
log("LDR %d -> %s = %d %%"
|
||||
% (raw, "HELL" if level else "DUNKEL", percent))
|
||||
if bridge is not None:
|
||||
bridge.publish("ldr", raw)
|
||||
bridge.publish("helligkeit", percent)
|
||||
|
||||
ra_raw, dec_raw = client.get_coordinates()
|
||||
ra_line, dec_line = format_coordinates(ra_raw, dec_raw)
|
||||
@@ -81,6 +93,11 @@ def poll_loop(display, client, interval=None, once=False,
|
||||
last_shown = (ra_line, dec_line)
|
||||
log("RA %-11s DEC %-12s -> %s | %s"
|
||||
% (ra_raw, dec_raw, ra_line, dec_line))
|
||||
if bridge is not None:
|
||||
bridge.publish("ra", ra_line)
|
||||
bridge.publish("dec", dec_line)
|
||||
if bridge is not None:
|
||||
bridge.publish("link", 1)
|
||||
except LinkError as e:
|
||||
# Kein Netz (WLAN): die Montierung gar nicht erst versuchen.
|
||||
log("Netz: %s" % e)
|
||||
@@ -95,6 +112,8 @@ def poll_loop(display, client, interval=None, once=False,
|
||||
log("Montierung: %s" % e)
|
||||
client.close()
|
||||
last_shown = _show_notice(display, config.NOLINK_LINES, last_shown, log)
|
||||
if bridge is not None:
|
||||
bridge.publish("link", 0)
|
||||
|
||||
if once:
|
||||
return last_shown
|
||||
|
||||
Reference in New Issue
Block a user