Raspi auf Sendung | Kommt bald: Raspi (m)isst Honig |
Um den „LoRaPi“ (Raspberry mit Lora Modul) nun für weitere Dienste zu verwenden, hier als Beispiel die Beschreibung für einen ein Autoresponser. Dabei muss der Raspberry den Meshtastic Nachrichten Stream abhören, die Nachrichten ausfiltern ob sie auch für den Node bestimmt sind, die Nachricht dann analysieren ob ein bestimmtes Wort vorkommt, um dann falls alles zutrifft, eine automatische Rückantwort an den herausgefilteren Absender zu schicken.
Aufbauend auf die bisherigen Tutorials (https://meshtastic.at/raspi-geht-stricken/ und https://meshtastic.at/raspi-auf-sendung/) beginnen wir mit dem Script welche den Nachrichtenstream abhört. Die beiden vorherigen Tutorials sind Bedingung, da die Meshtasticd Software und die meshtastic CLI Software unbedingt installiert sein müssen.
Die Meshtastic CLI Installation liefert die Anweisung meshtastic –listen um den Stream zu empfangen.
Diese Funktion bildet die Basis in folgendem Python Script, welches wir nun erstellen
Mit putty zum Raspi verbinden und folgendes in das Terminalfenster eingeben:
sudo nano listenall.py
Nun in die Datei das Script einfügen
ACHTUNG: die ID des Server Nodes muss unbedingt entsprechend ihrer NodeID geändert werden
8-stellige ID ohne !
# Server Node id des Autoresponders
target_to_id = „dd73d9f8„
Das Script:
#Script Autoresponder 15.Maerz 2025
import subprocess
import select
import re
import time
import sys
# Server Node id des Autoresponders
target_to_id = "dd73d9f8"
# Funktion zum Senden der Echo Nachricht
def send_message_to_sender(sender_id):
# Entferne das führende '!' aus der sender_id, falls vorhanden
sender_id = sender_id.lstrip('!')
# Nachricht an den Absender senden
message = "Holadrioooo Juhuu"
time.sleep(1)
result = subprocess.run(["/home/pi/meshtastic-env/bin/meshtastic", "--sendtext", message, "--dest", sender_id], capture_output=Tr>
if result.returncode == 0:
print(f"Nachricht erfolgreich gesendet an {sender_id}: {message}")
else:
print(f"Fehler beim Senden der Nachricht an {sender_id}: {result.stderr}")
# Funktion zum Überwachen des Streams
def read_stream(process):
payload = None
fromId = None
toId = None
while True:
reads, _, _ = select.select([process.stdout, process.stderr], [], [], 0.1)
for stream in reads:
line = stream.readline().strip()
if not line:
continue
# Prüfen, ob die Zeile den Start einer Text Nachricht markiert
if line.startswith("portnum: TEXT_MESSAGE_APP"):
payload = None
fromId = None
toId = None
# Extrahiere payload, also den Nachrichtentext
match_payload = re.search(r'payload:\s*"(.+?)"', line)
if match_payload:
payload = match_payload.group(1)
# Extrahiere fromId und toId, also Adsender und Empfänger ID
match_ids = re.search(r"'fromId': '(!.+?)', 'toId': '(!.+?)'", line)
if match_ids:
fromId = match_ids.group(1).lstrip("!")
toId = match_ids.group(2).lstrip("!")
# Wenn alle Werte vorhanden sind und die Nachricht an die richtige ToId geht
if payload and fromId and toId:
if toId == target_to_id and fromId != toId: # Ignoriert Nachrichten des Responders an sich selbst
if payload == "echo": #wenn der Nachrichtentext echo ist
print(f"Echo-Nachricht von {fromId} erkannt. Sende Antwort...")
send_message_to_sender(fromId)
print("Neustart des Skripts...")
# Restart des scripts erforderlich um den Stream weiterlesen zu können
process.terminate()
try:
process.wait(timeout=5) # Warte bis zu 5 Sekunden auf das Beenden des Prozesses
except subprocess.TimeoutExpired:
print("Prozess reagiert nicht, erzwinge Beendigung...")
process.kill() # Erzwinge das Beenden, falls nötig
# Neues Skript starten
subprocess.Popen([sys.executable] + sys.argv)
# Altes Skript beenden
sys.exit(0)
#print("Neustart des Skripts...")
#subprocess.Popen([sys.executable] + sys.argv) # Neues Skript starten
#sys.exit(0) # Altes Skript beenden
else:
print("Etwas empfangen, aber kein echo angefordert, daher nichts zu senden")
# Funktion zum Starten von meshtastic
def start_meshtastic():
return subprocess.Popen(
["/home/pi/meshtastic-env/bin/meshtastic", "--listen"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
)
def main():
process = start_meshtastic() # Starte meshtastic nur einmal
print("Starte Stream-Überwachung")
read_stream(process) # Lies den Stream und warte auf Nachrichten
if __name__ == "__main__":
main()
Mit STRG+x y enter speichern
Das script kann nun wie folgt gestartet werden:
phyton3 listenall.py
Wird nun eine Direktnachricht mit dem Text echo an das Node gesendet, so antwortet es mit Holadrioooo Juhuu

Um das „Reizwort“ von echo auf einen beliebigen anderen Wortlaut zu ändern, in der Datei listenall.py
if payload == „echo„: #wenn der Nachrichtentext echo ist
Nie NAchricht welche das Node zurücksenden soll, kann in der Datei hier geändert werden:
# Nachricht an den Absender senden
message = „Holadrioooo Juhuu„
Weil das Script sich permament nach dem Senden einer Antwort selbst restartet, kommt es vor dass der vorherige Prozess nicht sauber beendet wurde und der Raspi irgendwann immer langsamer wird. Deshalb wird nun ein zweites Script erstellt, welches in Intervallen von 30 Minuten läuft und alle laufenden meshtastic –listen und –sendtext Prozesse beendet, um das Script dann in bereinigtem RAM neu zu starten.
Zuerst das laufende Script mit Strg+c beenden. Im Zweifelsfalle des Raspi neu starten (sudo reboot)
Für die Erstellung des zweiten Scripts folgendes im Terminal eingeben:
sudo nano restart_autoresponder.py
Nun in die Datei folgendes Script einfügen:
import os
import subprocess
def kill_meshtastic_processes():
try:
# Liste aller Prozesse abrufen
result = subprocess.run(['ps', 'aux'], capture_output=True, text=True)
lines = result.stdout.split('\n')
for line in lines:
if 'meshtastic-' in line:
parts = line.split()
if len(parts) > 1:
pid = parts[1] # PID extrahieren
print(f"Beende Prozess mit PID: {pid}")
os.system(f'sudo kill -9 {pid}')
except Exception as e:
print(f"Fehler beim Beenden der Prozesse: {e}")
def start_listenall():
try:
command = "/home/pi/meshtastic-env/bin/python3 /home/pi/listenall.py &"
print("Starte listenall.py...")
os.system(command)
except Exception as e:
print(f"Fehler beim Starten von listenall.py: {e}")
if __name__ == "__main__":
kill_meshtastic_processes()
start_listenall()
mit strg+x y enter speichern
Nun ins Termial eingeben
crontab -e
Um das Script in Intervallen aufzurufen fügen wir folgende Zeile unten in die Datei ein (mit cursorsteuertasten ganz nach unten, mit Enter Leerzeile einfügen)
*/30 * * * * /usr/bin/sudo /usr/bin/python3 /home/pi/restart_autoresponder.py
mit strg+x y enter speichern
Nach einem Neustart wird nun auch der Autoresponder automatisch nach 30 Minuten gestartet
Soll der Autoresponder sofort nach Neustart aktiv sein, so kann in crontab die Zeile @reboot eingefügt werden, oder falls vorhanden die komplette anweisung mit && an die vorhandene Zeile anghängt werden
@reboot sleep 10 && /usr/bin/sudo /usr/bin/python3 /home/pi/restart_autoresponder.py
mit strg+x y enter speichern nicht vergessen
Gratuliere sie haben nun einen Meshtastic Autoresponder
Info: Für Erstellung des Scripts wurden mehrere Stunden aufgewendet damit es korrekt funktioniert, es kann jedoch bestimmt noch optimiert werden. Viel Spaß beim tüfteln 🙂
Raspi auf Sendung | Kommt bald: Raspi (m)isst Honig |