MQTT: Birth-Message + Last Will auf {MQTT_TOPIC}/status
- "online" (retained) beim (Re-)Connect via on_connect-Callback - "offline" automatisch durch Broker bei Verbindungsabbruch (LWT) - Abnehmer (n8n / Home Assistant) sehen jederzeit den Live-Zustand - README um Status-/Availability-Topic ergaenzt Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -138,6 +138,10 @@ Datenbank wie **NocoDB** ablegen.
|
|||||||
|
|
||||||
- Die Events werden auf dem Topic `{MQTT_TOPIC}/crossing` mit **QoS 1**
|
- Die Events werden auf dem Topic `{MQTT_TOPIC}/crossing` mit **QoS 1**
|
||||||
(nicht retained) publiziert.
|
(nicht retained) publiziert.
|
||||||
|
- Zusätzlich gibt es ein **Status-/Availability-Topic** `{MQTT_TOPIC}/status`
|
||||||
|
(retained): Beim Verbinden sendet die App `online` (Birth-Message), bei einem
|
||||||
|
Verbindungsabbruch publiziert der Broker automatisch `offline` (Last Will /
|
||||||
|
LWT). So lässt sich jederzeit erkennen, ob der Counter läuft.
|
||||||
- Das Payload ist JSON, z. B.:
|
- Das Payload ist JSON, z. B.:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
|||||||
14
app.py
14
app.py
@@ -73,9 +73,20 @@ MQTT_PASS = os.environ.get("MQTT_PASS")
|
|||||||
MQTT_TOPIC = os.environ.get("MQTT_TOPIC", "vehiclecounter/cam1")
|
MQTT_TOPIC = os.environ.get("MQTT_TOPIC", "vehiclecounter/cam1")
|
||||||
CAMERA_ID = os.environ.get("CAMERA_ID", "cam1")
|
CAMERA_ID = os.environ.get("CAMERA_ID", "cam1")
|
||||||
|
|
||||||
|
# Availability-/Status-Topic: "online" beim Verbinden (Birth-Message),
|
||||||
|
# "offline" automatisch via Last Will (LWT), falls die Verbindung abreisst.
|
||||||
|
STATUS_TOPIC = f"{MQTT_TOPIC}/status"
|
||||||
|
|
||||||
# Zeitzone fuer den Zeitstempel (DST-aware). Standard Europe/Berlin.
|
# Zeitzone fuer den Zeitstempel (DST-aware). Standard Europe/Berlin.
|
||||||
LOCAL_TZ = ZoneInfo(os.environ.get("TZ_NAME", "Europe/Berlin"))
|
LOCAL_TZ = ZoneInfo(os.environ.get("TZ_NAME", "Europe/Berlin"))
|
||||||
|
|
||||||
|
|
||||||
|
def _on_mqtt_connect(client, userdata, flags, *args):
|
||||||
|
"""Birth-Message: nach jedem (Re-)Connect 'online' (retained) senden."""
|
||||||
|
client.publish(STATUS_TOPIC, "online", qos=1, retain=True)
|
||||||
|
print(f"[mqtt] connected -> {STATUS_TOPIC} online", flush=True)
|
||||||
|
|
||||||
|
|
||||||
# paho-mqtt 2.x verlangt die CallbackAPIVersion, 1.x kennt sie nicht.
|
# paho-mqtt 2.x verlangt die CallbackAPIVersion, 1.x kennt sie nicht.
|
||||||
try:
|
try:
|
||||||
_mqtt = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
|
_mqtt = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
|
||||||
@@ -83,6 +94,9 @@ except AttributeError:
|
|||||||
_mqtt = mqtt.Client()
|
_mqtt = mqtt.Client()
|
||||||
if MQTT_USER:
|
if MQTT_USER:
|
||||||
_mqtt.username_pw_set(MQTT_USER, MQTT_PASS)
|
_mqtt.username_pw_set(MQTT_USER, MQTT_PASS)
|
||||||
|
_mqtt.on_connect = _on_mqtt_connect
|
||||||
|
# Last Will: Broker publiziert das, sobald die Verbindung unsauber abbricht.
|
||||||
|
_mqtt.will_set(STATUS_TOPIC, "offline", qos=1, retain=True)
|
||||||
try:
|
try:
|
||||||
# async + loop_start -> blockiert den App-Start nicht, wenn der Broker weg ist
|
# async + loop_start -> blockiert den App-Start nicht, wenn der Broker weg ist
|
||||||
_mqtt.connect_async(MQTT_HOST, MQTT_PORT, keepalive=60)
|
_mqtt.connect_async(MQTT_HOST, MQTT_PORT, keepalive=60)
|
||||||
|
|||||||
Reference in New Issue
Block a user