Berry-Skript für Tasmota:
So bindest du den Dragino LDS02 via LoRaWAN ein!

Vorwort: Worum geht es in diesem Skript?
Hier ist das Skript, das ich in diesem YouTube-Video vorgestellt habe. Ich habe es etwas optimiert und alles Unnötige entfernt, sodass nur noch der Teil mit dem LDS02 übrig geblieben ist. Das Skript ist besonders hilfreich, wenn man nicht nur die Daten per MQTT oder ähnliches auslesen möchte, sondern sie auch direkt auf der Web-UI darstellen will.
Falls ihr den Empfang eures LoRaWAN-ESP32 testen möchtet, schaut gerne hier vorbei: Dort findet ihr ein Skript, das alle 5 Sekunden eine Testnachricht sendet. Damit könnt ihr ganz einfach die Empfangsqualität prüfen und optimieren!
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

Damit das Skript funktioniert, müssen einige Bedingungen erfüllt sein:
- Es muss ein Sensor vorhanden sein, den man mittels
LoRaWANName1 xxx
in LDS02 umbenannt hat. - Es muss ein Feld mit „Name“ vorhanden sein und eines mit „Doorstatus“.
- Außerdem müssen folgende Einstellungen gesetzt werden:
- SetOption100 1: Entfernt
LwReceived
aus der JSON-Nachricht. - SetOption119 1: Entfernt die Geräteadresse aus dem JSON-Payload. Dies ist nützlich, wenn der Name bereits über
LoRaWANName
bekannt ist und die Adresse nicht benötigt wird.
- SetOption100 1: Entfernt
Wenn alles korrekt eingerichtet ist, wird euch auf der Web-UI folgendes angezeigt:
- Der Türstatus (offen/geschlossen).
- Die Signalstärke (RSSI) und Signalqualität (SNR).
- Die Uhrzeit der letzten Änderung.

Diese Informationen können vor allem bei der Inbetriebnahme sehr hilfreich sein.
Hinweis: Denkt daran, wie im Video erwähnt, den LDS02 fest auf eine Frequenz und einen SF (Spreading Factor) einzustellen. Detaillierte Informationen dazu findet ihr in meinem Video auf YouTube.
Erklärung der relevanten Zeilen
1. Initialisierung der Variablen
def init()
self.rssi_value = 0.0
self.snr_value = 0.0
self.door_status_value = "Tür Status unbekannt"
self.door_status_change_time = "0:00"
end
- Was passiert hier?
- Beim Start des Skripts werden die Variablen initialisiert, also mit „0-Werte“ beschrieben:
rssi_value
undsnr_value
speichern die Signalstärke und -qualität.door_status_value
speichert den aktuellen Türstatus.door_status_change_time
speichert die Uhrzeit der letzten Statusänderung.
- Beim Start des Skripts werden die Variablen initialisiert, also mit „0-Werte“ beschrieben:
2. Aktualisierung der Signalstärke (RSSI)
def update_rssi(value)
self.rssi_value = value
end
- Was passiert hier?
- Diese Methode aktualisiert den Wert der Signalstärke (
RSSI
), der in dBm gemessen wird.
- Diese Methode aktualisiert den Wert der Signalstärke (
3. Aktualisierung der Signalqualität (SNR)
def update_snr(value)
self.snr_value = value
end
- Was passiert hier?
- Diese Methode aktualisiert den Wert der Signalqualität (
SNR
), der in dB gemessen wird.
- Diese Methode aktualisiert den Wert der Signalqualität (
4. Aktualisierung der Uhrzeit
def update_time()
var t = tasmota.time_dump(tasmota.rtc()["local"])
self.door_status_change_time = format("%02d:%02d:%02d Uhr", t["hour"], t["min"], t["sec"])
end
- Was passiert hier?
- Die Methode holt die aktuelle Uhrzeit vom System (
tasmota.rtc()["local"]
). - Die Zeit wird im Format
HH:MM:SS Uhr
formatiert und indoor_status_change_time
gespeichert.
- Die Methode holt die aktuelle Uhrzeit vom System (
5. Änderung des Türstatus
def doorstatuschange(doorstatus)
if (doorstatus == 1)
self.door_status_value = "offen"
else
self.door_status_value = "geschlossen"
end
self.update_time()
end
- Was passiert hier?
- Diese Methode wird aufgerufen, wenn sich der Türstatus ändert.
- Wenn
doorstatus
den Wert1
hat, ist die Tür offen, sonst geschlossen. - Die Uhrzeit der letzten Änderung wird aktualisiert.
6. Anzeige der Daten auf der Webseite
def web_sensor()
webserver.content_send("<h1 style='font-size:32px; text-align:center;'>LDS02 Status</h1>")
webserver.content_send("<table style='width:100%; border-bottom:2px solid white; margin-bottom:10px;'>")
webserver.content_send("<tr><td></td></tr>")
webserver.content_send("</table>")
webserver.content_send("<div style='text-align:center; margin-bottom:10px; font-size:16px; font-weight:bold;'>")
webserver.content_send(format("{s}Türstatus:{m}%s{e}", self.door_status_value))
webserver.content_send("</div>")
webserver.content_send("<div style='text-align:center; margin-bottom:10px; font-size:smaller;'>")
webserver.content_send(format("{s}RSSI:{m}%.1f dBm{e}", self.rssi_value))
webserver.content_send(" ")
webserver.content_send(format("{s}SNR:{m}%.1f dB{e}", self.snr_value))
webserver.content_send("</div>")
webserver.content_send("<div style='text-align:center; margin-bottom:10px; font-size:smaller;'>")
webserver.content_send(format("{s}Letzte Änderung:{m}%s{e}", self.door_status_change_time))
webserver.content_send("</div>")
end
- Was passiert hier?
- Die Methode erstellt die Texte auf der Web-UI, die die gesammelten Daten anzeigt.
- Überschrift: „LDS02 Status“ in großer Schrift (32px) und zentriert.
- Trennlinie: Eine weiße, horizontale Linie (2px dick).
- Türstatus: Wird in fetter Schrift (16px) angezeigt.
- RSSI und SNR: Werden in einer Zeile mit kleinerer Schriftgröße angezeigt.
- Letzte Änderung: Die Uhrzeit der letzten Türstatusänderung wird in kleinerer Schriftgröße angezeigt.
7. Event-Handler für RSSI und SNR
tasmota.add_rule('RSSI', def (v,t,d) global.sensor_handler_instance.update_rssi(v) end)
tasmota.add_rule('SNR', def (v,t,d) global.sensor_handler_instance.update_snr(v) end)
- Was passiert hier?
- Diese Regeln aktualisieren die Werte für RSSI und SNR, sobald neue Daten empfangen werden.
8. Event-Handler für Türstatusänderung
tasmota.add_rule(['DoorOpen','Name=LDS02'],
def (values, trigger, data)
var doorstatus = values[0]
global.sensor_handler_instance.doorstatuschange(doorstatus)
end)
- Was passiert hier?
- Diese Regel wird ausgelöst, wenn sich der Türstatus ändert.
- Der neue Türstatus wird an die Methode
doorstatuschange
übergeben, um den Status und die Uhrzeit zu aktualisieren.
9. Gesamte Fertige Code
import webserver
class SensorHandler : Driver
var rssi_value
var snr_value
var door_status_value
var door_status_change_time # Speichert die Zeit der letzten Türstatusänderung
def init()
self.rssi_value = 0.0
self.snr_value = 0.0
self.door_status_value = " Tür Status unbekannt"
self.door_status_change_time = " 0:00 Uhr" # Initialzeit für die Türstatusänderung
end
def update_rssi(value)
self.rssi_value = value
end
def update_snr(value)
self.snr_value = value
end
def update_time()
var t = tasmota.time_dump(tasmota.rtc()["local"])
self.door_status_change_time = format("%02d:%02d:%02d Uhr", t["hour"], t["min"], t["sec"]) # Uhrzeit mit "Uhr" formatieren
end
def doorstatuschange(doorstatus)
print(f"Aktueller Türstatus: {self.door_status_value}")
if (doorstatus == 1)
self.door_status_value = " offen"
else
self.door_status_value = " geschlossen"
end
# Aktualisiere die Zeit nur, wenn sich der Türstatus ändert
self.update_time()
print(f"Türstatus geändert auf: {self.door_status_value} um {self.door_status_change_time}")
end
def web_sensor()
# Überschrift "LDS02 Status" mit Schriftgröße 32, zentriert
webserver.content_send("<h1 style='font-size:32px; text-align:center;'>LDS02 Status</h1>")
# Horizontale Trennlinie (weiß, 2px) mit Tabelle
webserver.content_send("<table style='width:100%; border-bottom:2px solid white; margin-bottom:10px;'>")
webserver.content_send("<tr><td></td></tr>") # Leere Zeile für die Trennlinie
webserver.content_send("</table>")
# Türstatus anzeigen (zentriert, Schriftgröße 16px, fett)
webserver.content_send("<div style='text-align:center; margin-bottom:10px; font-size:16px; font-weight:bold;'>")
webserver.content_send(format("{s}Türstatus:{m}%s{e}", self.door_status_value))
webserver.content_send("</div>")
# RSSI und SNR in einer Zeile, Schriftgröße 3 Stufen kleiner
webserver.content_send("<div style='text-align:center; margin-bottom:10px; font-size:smaller;'>")
webserver.content_send(format("{s}RSSI: {m}%.1f dBm{e}", self.rssi_value))
webserver.content_send(" ") # Abstand zwischen RSSI und SNR
webserver.content_send(format("{s}SNR: {m}%.1f dB{e}", self.snr_value))
webserver.content_send("</div>")
# Letzte Änderung (zentriert, Schriftgröße 3 Stufen kleiner)
webserver.content_send("<div style='text-align:center; margin-bottom:10px; font-size:smaller;'>")
webserver.content_send(format("{s}Letzte Änderung: {m}%s{e}", self.door_status_change_time))
webserver.content_send("</div>")
end
end
# Alte Instanz bereinigen
try
if global.sensor_handler_instance
tasmota.remove_driver(global.sensor_handler_instance)
end
except .. as e
print("Fehler beim Bereinigen der alten Instanz:", e)
end
# Neue Instanz erstellen
global.sensor_handler_instance = SensorHandler()
tasmota.add_driver(global.sensor_handler_instance)
# Event-Handler
tasmota.add_rule('RSSI', def (v,t,d) global.sensor_handler_instance.update_rssi(v) end)
tasmota.add_rule('SNR', def (v,t,d) global.sensor_handler_instance.update_snr(v) end)
# Türstatus-Regel
tasmota.add_rule(['DoorOpen','Name=LDS02'],
def (values, trigger, data)
var doorstatus = values[0] # Der ausgelöste Wert
var alarm = data['Alarm'] # Ein weiteres Feld aus der Nutzlast
global.sensor_handler_instance.doorstatuschange(doorstatus) # Setzt den Türstatus
end)
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.
⚠️ 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! 🙏