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:
+25
-1
@@ -96,7 +96,7 @@ def selftest(host=None, port=None, log=print):
|
||||
|
||||
|
||||
def main(host=None, port=None, with_ldr=False, fake_display=False,
|
||||
once=False, log=print):
|
||||
once=False, with_mqtt=True, log=print):
|
||||
"""WLAN aufbauen, Anzeige oeffnen und die Poll-Schleife fahren.
|
||||
|
||||
host/port Montierung; Vorgabe aus config.py. Zum Testen gegen den Mock
|
||||
@@ -108,6 +108,9 @@ def main(host=None, port=None, with_ldr=False, fake_display=False,
|
||||
fake_display Anzeige nur als Hex in die REPL schreiben, statt ueber den
|
||||
UART zu senden -- fuer den Test ohne Pegelwandler und Anzeige.
|
||||
once nur ein Durchlauf, dann zurueck.
|
||||
with_mqtt MQTT-Anbindung versuchen. Ohne mqtt_config.py passiert nichts,
|
||||
deshalb ist die Vorgabe an: fehlt die Datei, laeuft alles wie
|
||||
bisher weiter.
|
||||
"""
|
||||
d = open_display(fake=fake_display)
|
||||
client = MountClient(config.MOUNT_HOST if host is None else host,
|
||||
@@ -122,6 +125,7 @@ def main(host=None, port=None, with_ldr=False, fake_display=False,
|
||||
else:
|
||||
dimmer = BrightnessController()
|
||||
|
||||
bridge = None
|
||||
try:
|
||||
# Einmal vorab verbinden, damit ein Fehler gleich sichtbar wird; danach
|
||||
# haelt ensure_link die Verbindung in der Schleife.
|
||||
@@ -130,14 +134,34 @@ def main(host=None, port=None, with_ldr=False, fake_display=False,
|
||||
except wifi.WifiError as e:
|
||||
log("WLAN: %s" % e)
|
||||
|
||||
if with_mqtt:
|
||||
import mqtt
|
||||
# Kommt per MQTT eine neue Helligkeit, muss der Dimmer sie sofort
|
||||
# sehen -- sonst wirkte sie erst nach einem Neustart.
|
||||
def uebernehmen(werte):
|
||||
if dimmer is not None:
|
||||
dimmer.reload()
|
||||
# Ohne LDR gibt es keinen Stufenwechsel, der die Helligkeit
|
||||
# nachzieht: dann direkt die helle Stufe setzen.
|
||||
if dimmer is None:
|
||||
try:
|
||||
d.set_brightness(werte["hell_prozent"])
|
||||
except Exception as e:
|
||||
log("Anzeige: %s" % e)
|
||||
|
||||
bridge = mqtt.connect_from_config(log=log, on_change=uebernehmen)
|
||||
|
||||
displayloop.poll_loop(d, client,
|
||||
once=once,
|
||||
read_ldr=read_ldr,
|
||||
dimmer=dimmer,
|
||||
ensure_link=lambda: wifi.ensure(log=log),
|
||||
bridge=bridge,
|
||||
log=log)
|
||||
except KeyboardInterrupt:
|
||||
log("\nbeendet")
|
||||
finally:
|
||||
if bridge is not None:
|
||||
bridge.close()
|
||||
client.close()
|
||||
d.close()
|
||||
|
||||
Reference in New Issue
Block a user