Ein Skript, das auf MQTT-Nachrichten lauscht und sie in einer JSON-Struktur zusammengefasst ablegt und Änderungen darin aktualisiert, wenn eine neue Nachricht eintrifft.
Die JSON-Datei kann dann für ein Webbrowser-Status-UI leichter in einem einzigen Arbeitsgang abgerufen und ausgewertet werden, ohne jedes Topic neu abfragen/subscriben zu müssen.
nano /home/pi/mqtt_bridge.sh
#!/bin/bash
STORAGE_FILE="/home/pi/public_html/mqtt_states.json"
MAX_LENGTH=500
# Initialize storage
if [ ! -f "$STORAGE_FILE" ]; then
echo "{}" > "$STORAGE_FILE"
chmod 666 "$STORAGE_FILE"
fi
mosquitto_sub -h localhost -t "#" -F "%j" | while read -r line; do
TOPIC=$(echo "$line" | jq -r '.topic')
PAYLOAD=$(echo "$line" | jq -r '.payload')
# Skip if payload is too large
if [ ${#PAYLOAD} -gt $MAX_LENGTH ]; then
continue
fi
# Clean the payload and get current timestamp
CLEAN_PAYLOAD="${PAYLOAD%$'\n'}"
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
# 2. Use jq to "try" parsing the payload as JSON.
# If it fails (like for plain numbers), treat it as a raw string.
# The 'fromjson? // .' trick is the magic here.
jq --arg t "$TOPIC" \
--arg p "$CLEAN_PAYLOAD" \
--arg ts "$TIMESTAMP" \
'.[$t] = {"ts": $ts, "val": ($p | fromjson? // .)}' \
"$STORAGE_FILE" > "${STORAGE_FILE}.tmp" && \
mv "${STORAGE_FILE}.tmp" "$STORAGE_FILE"
done
Hier noch der systemd-Eintrag dazu:
sudo nano /etc/systemd/system/mqtt-bridge.service
[Unit] Description=MQTT to JSON Local Storage Bridge # Wait for network and Mosquitto to be ready After=network-online.target mosquitto.service Wants=network-online.target mosquitto.service [Service] # Replace 'youruser' with your actual Debian username User=pi ExecStart=/bin/bash /home/pi/mqtt_bridge.sh Restart=always RestartSec=5 # Ensures the script has a clean environment StandardOutput=inherit StandardError=inherit [Install] WantedBy=multi-user.target