Häufig gestellte Frage

Kopplung Meshtastic Notfallbox
Zuletzt aktualisiert vor 3 Tagen

Wie man die Notfallbox per MQTT und Meshtastic zusammenbringen kann - eine Idee von unserem Nutzer Sebastian.

Sebastian hat angeregt, die Notfallbox mit der Fähigkeit zu versehen, per MQTT-Protokoll mit meshtastic-Knoten (LoRa) zusammenarbeiten zu können. Da dies bei uns derzeit nicht im Fokus liegt, haben wir ihn gebeten, entsprechende Ergebnisse für andere Benutzer zusammen zu stellen. Ob und wie wir dies dauerhaft in der Notfallbox unterbringen werden, ist noch nicht entschieden.

Nachfolgend nun die Anweisungen von Sebastian, zur Selbstintegration.


Se

  1. Voraussetzungen:
    • MariaDB läuft bereits.
    • Datenbank notfallbox, Tabelle mqtt (Spalten: id, date, topic, length, message) ist vorhanden.
    • DB-Benutzer notfallbox / Passwort notfallbox besitzt Schreibrechte auf diese DB.
  2. Konfiguration des meshtastic-Knotens zur Zusammenarbeit mit der Notfallbox.
    image
  3. Software installieren
    sudo apt update 
    sudo apt install -y mosquitto mosquitto-clients mariadb-server jg 
    sudo systemctl enable --now mosquitto.service # MQTT-Broker dauerhaft aktiv

  4. Skript anlegen
    sudo nano /usr/local/bin/mqtt-to-mariadb.sh

    Inhalt von mqtt-to-mariadb.sh:


    #!/usr/bin/env bash
    #
    # MQTT ➜ MariaDB Logger
    # -------------------------------------------------------------
    # • Lauscht auf *alle* MQTT-Topics des lokalen Brokers.
    # • Verarbeitet nur JSON-Payloads mit "type":"text".
    # • Nutzt den Zeitstempel aus "timestamp" (Fallback: Systemzeit).
    # • Übersetzt channel-Nummern in Klartext-Namen (siehe CHANNEL_LABELS).
    #   – Channel 0 heißt standardmäßig „Allgemein“,
    #   – außer wenn  to == NODE_ID  ⇒ NODE_NAME.
    # • Hängt an den Nachrichtentext ein Suffix:
    #     (Sender: <4 Zeichen>, SNR: , RSSI: , Entfernung:  hops)
    # • Schreibt in Tabelle  notfallbox.mqtt  (date, topic, length, message).
    # • Loggt RAW-JSON + ASCII-Tabelle (erste 200 Zeichen der Message).
    # -------------------------------------------------------------
    
    set -euo pipefail
    
    # ───── MQTT ─────
    BROKER_HOST="localhost"
    BROKER_PORT=1883
    MQTT_SUB_CMD=(mosquitto_sub -v -h "$BROKER_HOST" -p "$BROKER_PORT" -t '#')
    
    # ───── Datenbank ─────
    DB_USER="notfallbox"
    DB_PASS="notfallbox"
    DB_NAME="notfallbox"
    DB_TABLE="mqtt"
    
    # ───── Eigener Mesh-Knoten ─────
    NODE_ID=2425773576
    NODE_NAME="Notfall"
    
    # ───── Kanal-Labels ─────
    declare -A CHANNEL_LABELS=(
      [0]="Allgemein"
      [1]="Besslich"
      [2]="Trier"
      [3]="RLP"
      [4]="Rhein Mesh"
      [5]="Amateur Funk"
      [6]="OFF Topic"
    )
    
    # channel / to  ➜  Klartext
    label_channel() {
      local ch="$1" to="$2"
      if [[ $ch -eq 0 ]]; then
        [[ $to -eq $NODE_ID ]] && echo "$NODE_NAME" || echo "${CHANNEL_LABELS[0]}"
      else
        echo "${CHANNEL_LABELS[$ch]:-"Channel $ch"}"
      fi
    }
    
    # Rahmen für ASCII-Tabelle
    border() { printf '+----------------------+----------------------+--------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+\n'; }
    
    # Datensatz → DB + Log
    insert_row() {
      local ts="$1" topic="$2" msg="$3"
      local len=${#msg}
    
      mysql -u "$DB_USER" -p"$DB_PASS" "$DB_NAME" 2>/dev/null \
            --execute "INSERT INTO $DB_TABLE (date, topic, length, message)
                       VALUES ($ts, '$(printf %q "$topic")', $len, '$(printf %q "$msg")');"
    
      local human; human=$(date -d @"$ts" '+%Y-%m-%d %H:%M:%S')
      border
      printf '| %-20s | %-20s | %-6s | %-200s |\n' \
             "$human" "$(printf %.20s "$topic")" "$len" "$(printf %.200s "$msg")"
      border
    }
    
    # ───── Haupt-Loop ─────
    "${MQTT_SUB_CMD[@]}" | while IFS= read -r line; do
      payload=${line#*" "}                         # Topic abschneiden
      jq -e . >/dev/null 2>&1 <<<"$payload"  || continue
      [[ $(jq -r '.type // empty' <<<"$payload") == "text" ]] || continue
    
      echo "$payload"                             # RAW-JSON
    
      ts=$(jq -r '.timestamp // empty'      <<<"$payload"); [[ -z $ts ]] && ts=$(date +%s)
      ch=$(jq -r '.channel // empty'        <<<"$payload")
      to=$(jq -r '.to // empty'             <<<"$payload")
      txt=$(jq -r '.payload.text // empty'  <<<"$payload")
      sender=$(jq -r '.sender // empty'     <<<"$payload")
      snr=$(jq -r '.snr // empty'           <<<"$payload")
      rssi=$(jq -r '.rssi // empty'         <<<"$payload")
      hops=$(jq -r '.hops_away // empty'    <<<"$payload")
      [[ -z $txt ]] && continue
    
      suffix=" (Sender: ${sender: -4}, SNR: ${snr} dB, RSSI: ${rssi} dBm, Entfernung: ${hops} hops)"
      insert_row "$ts" "$(label_channel "$ch" "$to")" "${txt}${suffix}"
    done
    
  5. Skript ausführbar machen

    sudo chmod 755 /usr/local/bin/mqtt-to-mariadb.sh
  6. systemd-Dienst erstellen

    sudo nano /etc/systemd/system/mqtt-to-mariadb.service

    Inhalt der Datei mqtt-to-maridb.service
    [Unit]
    Description=MQTT ➜ MariaDB Logger
    After=network-online.target mariadb.service mosquitto.service
    Wants=network-online.target
    
    [Service]
    ExecStart=/usr/local/bin/mqtt-to-mariadb.sh
    # -----------------------------------------------------------------
    # Standardmäßig läuft die Unit als root.  Wenn du sie künftig
    # unter einem bestimmten Benutzer starten möchtest, einfach die
    # nächsten zwei Zeilen aktivieren und anpassen:
    #
    #User=notfallbox
    #Group=notfallbox
    # -----------------------------------------------------------------
    Restart=on-failure
    StandardOutput=journal
    StandardError=journal
    
    [Install]
    WantedBy=multi-user.target
  7. systemd-Dienst neu laden / starten

    sudo systemctl daemon-reload
    sudo systemctl enable --now mqtt-to-mariadb.service
  8. Live-Test
    1. Log mitlaufen lassen
      journalctl -u mqtt-to-mariadb.service -f
    2. Testnachricht
      mosquitto_pub -h localhost -t msh/test -m \ '{"channel":0,"to":2425773576,"type":"text","timestamp":1748089000,"payload":{"text":"Hallo Welt"},"sender":"!90965e08","snr":7.0,"rssi":-20,"hops_away":0}'
    3. Datenbank prüfen
      mariadb -u notfallbox -pnotfallbox -e \"SELECT date,topic,length,LEFT(message,80) FROM notfallbox.mqtt ORDER BY id DESC LIMIT 5;"
    4. Man sollte nun in journalctl die RAW-JSON-Zeile und darunter die ASCII-Tabelle sehen – und in der Datenbank einen neuen Eintrag mit Topic „Notfall“.

  9. Wenn gewünscht, kann der Benutzer, unter welchem der Service läuft in der Datei /etc/systemd/system/mqtt-to-mariadb.service geändert werden. Hier müssen nur folgende Zeilen auskommentiert und geändert werden:
    #User=notfallbox
    #Group=notfallbox
    Im Anschluss unbedingt den Service neu starten:
    sudo systemctl daemon-reload
    sudo systemctl restart mqtt-to-mariadb.service
    Falls anschließend status=217/USER oder 216/GROUP erscheint, prüfe Tippfehler und dass
    getent passwd notfallbox
    bzw.
    getent group notfallbox
    jeweils einen Eintrag ausgeben.
  10. Vorschlag für eine Inhaltsänderung der Datei /var/www/html/mqtt.php

Sebastian empfiehlt weiterhin die Änderung der Datei /var/www/html/mqtt.php. Die Änderung beinhaltet eine 10 Sekündliche automatische Aktualisierung sowie eine Ordnung der Nachrichtenliste absteigend (also neuester Eintrag zuerst).

Bitte Datei herunterladen und speichern: mqtt.php

Die Änderung ergibt dann folgendes Aussehen:

image

Bitte warten!

Bitte warten... es dauert eine Sekunde!