MQTT / Mosquitto und Webserver

16 Apr.

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

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

13 − neun =