Berry-Skript für Sender-/Empfänger-Test:

LoRa-Empfangsqualität einfach prüfen und optimieren!

LoRa & Tasmota Sender-/Empfänger Test

Testen der Empfangsqualität von LoRa-Nachrichten

In der Welt des Smart Homes und der drahtlosen Kommunikation ist eine zuverlässige Datenübertragung essenziell. Gerade bei LoRa, einer stromsparenden Funktechnologie mit großer Reichweite, möchte man sicherstellen, dass die gesendeten Nachrichten tatsächlich beim Empfänger ankommen. Doch wie überprüft man das am besten?

Ein simples, aber effektives Berry-Skript kann dabei helfen, den Empfang zu testen und mögliche Fehlerquellen aufzudecken. Mit diesem Skript lässt sich nicht nur nachvollziehen, ob Nachrichten korrekt empfangen werden, sondern auch, wie stabil die Verbindung ist und welche Signalqualität vorliegt.

Weiterführende Informationen zu LoRa, LoRaWAN usw. findet ihr auf der Tasmota GitHub Seite.


Verwendete Hardware:

Affiliate-Links:
»Heltec« ☛ https://amzn.to/3XlQ47q
»LilyGo« ☛ https://amzn.to/3XkM5rG
»Dragino« ☛ https://amzn.to/3D9BlWs


Falls ihr den Dragino LDS02 in euer Smart Home integrieren möchtet und dabei Tasmota und LoRaWAN nutzen? Dann solltet ihr unbedingt diesen Artikel lesen! Hier erfahrt ihr, wie ihr mit einem Berry-Skript den LDS02-Türsensor einbindet und Daten wie TürstatusRSSISNR und die Uhrzeit der letzten Änderung auf der Web-UI anzeigt. Das Skript ist perfekt für alle, die ihren LoRaWAN-Empfang optimieren und den LDS02 effizient in ihr Smart-Home-System einbinden möchten. 

image

YouTube-Videos zum Thema

Zu diesem Thema gibt es zwei ausführliche YouTube-Videos, die sich intensiv mit Tasmota, LoRa und LoRaWAN beschäftigen. In diesen Videos erkläre ich euch alle Grundlagen, zeige euch, wie ihr Tasmota richtig konfiguriert, welche Hardware ihr benötigt und führe euch Schritt für Schritt durch den gesamten Prozess – einfach, verständlich und praxisnah.

Da das Thema recht komplex ist, sind die Videos etwas länger geworden. Doch keine Sorge – sie sind so aufgebaut, dass ihr alles nachvollziehen und direkt umsetzen könnt. Besonders für Einsteiger sind diese Videos eine wertvolle Ressource, um die Basics zu verstehen und erfolgreich mit LoRa und Tasmota zu arbeiten. Schaut also unbedingt rein! 🚀

Das Sender-Skript – Nachrichten zuverlässig versenden

TasmotaSenderLora

Das Sender-Skript ist bewusst simpel gehalten, um eine klare und verständliche Testumgebung zu schaffen. Seine Aufgabe ist es, in regelmäßigen Abständen Nachrichten per LoRa zu senden. Konkret sieht das folgendermaßen aus:

  • Alle 5 Sekunden wird eine neue Nachricht verschickt.
  • Die Nachricht enthält die fortlaufende Nummer der Übertragung im Format:
    „Nachricht Nr.: xxx“, wobei xxx für die Anzahl der bereits gesendeten Nachrichten steht.
  • In der Tasmota Web-UI wird die Anzahl der gesendeten Nachrichten übersichtlich dargestellt, sodass jederzeit überprüft werden kann, wie viele Pakete bereits verschickt wurden.

Dieses einfache Konzept ermöglicht eine kontinuierliche Überwachung des Nachrichtenflusses. Sollte es zu Verbindungsabbrüchen oder verlorenen Nachrichten kommen, lässt sich dies anhand der Zahlen schnell erkennen.

Sender

Berry
import webserver

class SensorHandler : Driver
  var counter1_value  # Zähler für gesendete Nachrichten

  def init()
    self.counter1_value = 0  # Initialer Zählerwert für LoRa gesendet
    
    # Timer einrichten, um alle 5 Sekunden eine LoRa-Nachricht zu senden
    tasmota.add_cron("*/5 * * * * *", /-> self.send_lora_message(), "LoRaTimer")
  end

  def send_lora_message()
    self.counter1_value += 1  # Zähler für gesendete Nachrichten erhöhen
    var message = "Nachricht Nr.: " + str(self.counter1_value)  # Nachricht mit Zählerwert erstellen
    tasmota.cmd("Lorasend2 " + message)  # LoRa-Nachricht senden
  end

  def web_sensor()
    # Überschrift
    webserver.content_send("<div style='text-align:center;font-size:32px;margin:10px 0;'>LoRa Sender</div>")

    # Erste horizontale Trennlinie
    webserver.content_send("<hr>")

    # Tabelle für LoRa gesendet
    webserver.content_send("<table style='width:100%;'>")
    webserver.content_send("<tr><td>")
    webserver.content_send(format("{s}<span style='color:red;'>LoRa gesendet:{m}%d</span>{e}", self.counter1_value))
    webserver.content_send("</td></tr>")
    webserver.content_send("</table>")

    # Zweite horizontale Trennlinie
    webserver.content_send("<hr>")
  end
end

# Instanziierung des Treibers und Entfernen der alten Instanz
global.sensor_handler_instance = SensorHandler()
tasmota.remove_driver(global.sensor_handler_instance)

# Neue Treiberinstanz hinzufügen
tasmota.add_driver(global.sensor_handler_instance)

Vollständige Code anzeigen

Das Empfänger-Skript – Nachrichten auswerten und analysieren

TasmotaEmpfaengerLora

Auf Empfängerseite wird es etwas spannender. Hier übernimmt das Skript gleich mehrere Aufgaben, um nicht nur den Empfang zu bestätigen, sondern auch wichtige Informationen zur Signalqualität zu liefern.

1. Zählen der empfangenen Nachrichten

Zunächst wird jede empfangene LoRa-Nachricht gezählt. Dies gibt einen ersten Hinweis darauf, ob sämtliche gesendeten Nachrichten auch wirklich ankommen. Dabei ist zu beachten, dass das Skript alle eingehenden LoRa-Nachrichten erfasst – auch solche, die möglicherweise von anderen Geräten in der Umgebung stammen.

Sollte also zufällig jemand in der Nachbarschaft mit derselben Frequenz und demselben Spreading-Faktor (SF) senden, könnte dies zu zusätzlichen Zählungen führen. In der Praxis ist dieses Szenario jedoch eher unwahrscheinlich.

2. Analyse der Signalqualität (RSSI und SNR)

Neben der reinen Anzahl der empfangenen Nachrichten ist es auch wichtig zu wissen, wie gut das Signal tatsächlich ist. Deshalb wertet das Skript zwei entscheidende Parameter aus:

  • RSSI (Received Signal Strength Indicator) – Gibt die Signalstärke an. Ein niedriger Wert bedeutet, dass das Signal schwach ist und möglicherweise Störungen oder eine zu große Entfernung zwischen Sender und Empfänger vorliegt.
  • SNR (Signal-to-Noise Ratio) – Zeigt das Verhältnis von Nutzsignal zu Störgeräuschen. Ein hoher SNR-Wert bedeutet eine bessere Empfangsqualität, während ein niedriger Wert darauf hindeutet, dass das Signal stark von Rauschen beeinflusst wird.

Beide Werte werden in der Tasmota Web-UI dargestellt, sodass man auf einen Blick erkennen kann, wie gut die Verbindung zwischen Sender und Empfänger ist.

3. Anzeige der empfangenen Nachrichten

Zu guter Letzt wird auch der Inhalt der empfangenen Nachrichten direkt angezeigt. Dies dient der Kontrolle, ob die empfangenen Daten mit den gesendeten übereinstimmen und ob möglicherweise Übertragungsfehler aufgetreten sind.

Ein besonderer Fokus liegt dabei auf dem Abgleich zwischen:

  • der Anzahl der empfangenen Nachrichten (LoRa empfangen)
  • und der tatsächlich angezeigten Nachricht (Empfangene Nachricht).

Wenn beide Werte übereinstimmen, funktioniert die Kommunikation einwandfrei. Falls jedoch Diskrepanzen auftreten, kann dies auf verlorene Pakete oder Störungen im Funkverkehr hindeuten.Das Skript auf Empfänger Seite ist etwas länger da es mehrere Funktionen enthält.

Empfänger

Berry
import webserver

class SensorHandler : Driver
  var counter1_value
  var rssi_value
  var snr_value
  var last_received_timestamp
  var NachrichtTxt  # Variable für die bereinigte Nachricht

  def init()
    self.counter1_value = 0
    self.rssi_value = 0
    self.snr_value = 0
    self.last_received_timestamp = "00:00:00"
    self.NachrichtTxt = ""  # Initialisiere die Variable
    
    tasmota.cmd("Rule1 ON LoRaReceived DO Backlog Var1 1; Var2 %timestamp%; Var4 %value% ENDON")
    tasmota.cmd("Rule1 1")
  end

  def update_counter1(value)
    self.counter1_value = self.counter1_value + 1
  end

  def update_rssi(value)
    self.rssi_value = format("%.1f", value)
  end

  def update_snr(value)
    self.snr_value = format("%.1f", value)
  end

  def update_timestamp(value)
    var time_dump = tasmota.time_dump(value)
    if time_dump != nil
      self.last_received_timestamp = format("%02d:%02d:%02d", time_dump["hour"], time_dump["min"], time_dump["sec"])
    else
      self.last_received_timestamp = "N/A"
    end
  end

  def update_message(value)
    # Konvertiere den Wert in einen String, falls es sich um ein map-Objekt handelt
    var message = str(value)
    
    # Manuelle Extraktion der Nachricht aus dem JSON-Format
    var prefix = "'State': '"
    var suffix = "'}"
    var prefix_len = size(prefix)
    var suffix_len = size(suffix)
    
    var prefix_pos = -1
    var suffix_pos = -1
    
    # Finde die Position des Präfix
    for i : 0 .. size(message) - prefix_len
      if message[i..i+prefix_len-1] == prefix
        prefix_pos = i + prefix_len
        break
      end
    end
    
    # Finde die Position des Suffix
    if prefix_pos >= 0
      for i : prefix_pos .. size(message) - suffix_len
        if message[i..i+suffix_len-1] == suffix
          suffix_pos = i
          break
        end
      end
    end
    
    # Extrahiere die Nachricht
    if prefix_pos >= 0 && suffix_pos >= 0
      self.NachrichtTxt = message[prefix_pos..suffix_pos-1]
    else
      self.NachrichtTxt = message  # Falls kein JSON-Format, speichere die Nachricht direkt
    end
    
    print("Empfangene Nachricht:", self.NachrichtTxt)
  end

  def web_sensor()
    # Verwende die bereinigte Nachricht in der Web-UI
    webserver.content_send("<div style='text-align:center;font-size:32px;margin:10px 0;'>LoRa Empfänger</div>")
    webserver.content_send("<hr>")
    webserver.content_send("<table style='width:100%;'>")
    webserver.content_send("<tr><td>")
    webserver.content_send(format("{s}<span style='color:green;'>LoRa empfangen:{m}%d</span>{e}", self.counter1_value))
    webserver.content_send("</td></tr>")
    webserver.content_send("<tr><td>")
    webserver.content_send(format("{s}RSSI ist:{m}%s{e}", self.rssi_value))
    webserver.content_send("</td></tr>")
    webserver.content_send("<tr><td>")
    webserver.content_send(format("{s}SNR ist:{m}%s{e}", self.snr_value))
    webserver.content_send("</td></tr>")
    webserver.content_send("<tr><td>")
    webserver.content_send(format("{s}Letzter Empfangszeitstempel: {m}%s{e}", self.last_received_timestamp))
    webserver.content_send("</td></tr>")
    webserver.content_send("<tr><td>")
    webserver.content_send(format("{s}Empfangene Nachricht: {m}%s{e}", self.NachrichtTxt))  # Verwende die bereinigte Nachricht
    webserver.content_send("</td></tr>")
    webserver.content_send("</table>")
    webserver.content_send("<hr>")
  end
end

global.sensor_handler_instance = SensorHandler()
tasmota.remove_driver(global.sensor_handler_instance)
tasmota.add_driver(global.sensor_handler_instance)

tasmota.add_rule('Var1#State', /value, trigger, data -> global.sensor_handler_instance.update_counter1(value))
tasmota.add_rule('Var2', /value, trigger, data -> global.sensor_handler_instance.update_timestamp(tasmota.rtc()["local"]))
tasmota.add_rule('Var4#State', /value, trigger, data -> global.sensor_handler_instance.update_message(value))tasmota.add_rule('RSSI', /value, trigger, data -> global.sensor_handler_instance.update_rssi(value))
tasmota.add_rule('SNR', /value, trigger, data -> global.sensor_handler_instance.update_snr(value))
Vollständige Code anzeigen

Hinweis und Community-Beitrag

Ich bin kein professioneller Programmierer, sondern ein begeisterter Smart-Home-Enthusiast, der gerne mit LoRa und Tasmota experimentiert. Daher kann es sein, dass das Skript nicht perfekt ist oder sich bestimmte Dinge noch optimieren lassen.

Falls euch beim Testen Fehler auffallen oder ihr Ideen habt, wie man das Skript verbessern kann, freue ich mich über euer Feedback! Schreibt mir gerne eure Vorschläge, und ich werde sinnvolle Änderungen übernehmen. Natürlich werde ich jede Anpassung nur mit eurer Zustimmung veröffentlichen, sodass die Community von den Verbesserungen profitieren kann.

Gemeinsam können wir das Skript weiterentwickeln und optimieren – für eine noch zuverlässigere LoRa-Kommunikation in unseren Smart-Home-Projekten! 🚀

⚠️ Hinweis zu Affiliate-Links:
Alle Links zu Produkten auf dieser Website sind Affiliate-Links. Durch das Anklicken dieser Links unterstützt du meine Arbeit und hilfst mir, diese Website zu finanzieren.
Für dich entstehen dabei keine zusätzlichen Kosten – der Preis bleibt gleich.
Ich erhalte lediglich eine kleine Provision vom Händler oder Amazon. Vielen Dank für deine Unterstützung! 🙏