From c5aced3dd0b7357758cf1a6b54e4fd19114df633 Mon Sep 17 00:00:00 2001 From: UBWH <72185209+UBWH@users.noreply.github.com> Date: Sat, 5 Jul 2025 21:18:45 +0800 Subject: [PATCH] Create SE01-L.be (#23607) LoRaWAN decoder for Dragino SE01-LB/LS -- LoRaWAN Soil Moisture & EC Sensor --- .../decoders/vendors/dragino/SE01-L.be | 145 ++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 tasmota/berry/lorawan/decoders/vendors/dragino/SE01-L.be diff --git a/tasmota/berry/lorawan/decoders/vendors/dragino/SE01-L.be b/tasmota/berry/lorawan/decoders/vendors/dragino/SE01-L.be new file mode 100644 index 000000000..417d1ca91 --- /dev/null +++ b/tasmota/berry/lorawan/decoders/vendors/dragino/SE01-L.be @@ -0,0 +1,145 @@ +# LoRaWAN Decoder file for Dragino SE01-LB/LS Soil Sensor +# URL: https://www.dragino.com/products/agriculture-weather-station/item/277-se01-lb.html +# File Name: SE01-L.be +# +# References +# User Manual: https://wiki.dragino.com/xwiki/bin/view/Main/User%20Manual%20for%20LoRaWAN%20End%20Nodes/SE01-LB_LoRaWAN_Soil%20Moisture%26EC_Sensor_User_Manual/ +# TTN Device Repository:https://github.com/TheThingsNetwork/lorawan-devices/blob/master/vendor/dragino/lse01-121.js + +import string + +global.se01LNodes = {} + +class LwDecoSE01L + static def decodeUplink(Node, RSSI, FPort, Bytes) + var data = {"Device":"Dragino SE01-LB/LS"} + data.insert("Node", Node) + + var valid_values = false + var last_seen = 1451602800 + var battery_last_seen = 1451602800 + var battery = 1000 + var rssi = RSSI + + var temp = 1000 + var conductivity=0 + var moisture=0 + var dielectric=0 + var mod + var i_flag # 0: Normal uplink packet, 1: Interrupt Uplink Packet. + var s_flag # 0: No sensor was identified, 1: The sensor has been identified + + if global.se01LNodes.find(Node) + last_seen = global.se01LNodes.item(Node)[1] + battery_last_seen = global.se01LNodes.item(Node)[2] + battery = global.se01LNodes.item(Node)[3] + rssi = global.se01LNodes.item(Node)[4] + + temp = global.se01LNodes.item(Node)[5] + conductivity = global.se01LNodes.item(Node)[6] + moisture = global.se01LNodes.item(Node)[7] + dielectric = global.se01LNodes.item(Node)[8] + end + + ## SENSOR DATA ## + #e.g. 0f5a 0ccc 0000 079d 0000 10 + # Battery ExtTemp Moisture Temp EC Mode,Flags + if 2 == FPort && ( Bytes.size() == 11 || Bytes.size() == 15) + last_seen = tasmota.rtc('local') + + battery_last_seen = tasmota.rtc('local') + battery=((Bytes[0]<<8 | Bytes[1]) & 0x3FFF)/1000.0 ##Battery,units:V + s_flag = (Bytes[10] >> 4) & 0x01 + i_flag = Bytes[10] & 0x0f + mod=(Bytes[10]>>7)&0x01 + + if 0==mod #Default mode + moisture=((Bytes[4]<<8 | Bytes[5])/100.0) ##moisture,units:% + conductivity=Bytes[8]<<8 | Bytes[9] + var value=Bytes[6]<<8 | Bytes[7] + if((value & 0x8000)>>15 == 0) + temp=(value/100.0) + else + temp=((value-0xFFFF)/100.0) + end + data.insert("Mode", "Default") + data.insert("Temp", temp) + + else #Raw Data mode + conductivity=Bytes[4]<<8 | Bytes[5] + moisture = Bytes[6]<<8 | Bytes[7] + dielectric = ((Bytes[8]<<8 | Bytes[9])/10.0) + data.insert("Mode", "Raw") + data.insert("DielectricConstant", dielectric) + end + + data.insert("BattV",battery) + data.insert("Moisture", moisture) + data.insert("Conductivity", conductivity) + data.insert("i_flag", i_flag) + data.insert("s_flag", s_flag) + + valid_values = true + + ## STATUS DATA ## + elif 5 == FPort && Bytes.size() == 7 + data.insert("Sensor_Model",Bytes[0]) + data.insert("Firmware_Version", f'v{Bytes[1]:%u}.{Bytes[2]>>4:%u}.{Bytes[2]&0xF:%u}') + data.insert("Freq_Band",LwRegions[Bytes[3]-1]) + data.insert("Sub_Band",Bytes[4]) + data.insert("BattV",((Bytes[5] << 8) | Bytes[6]) / 1000.0) + battery_last_seen = tasmota.rtc('local') + battery = ((Bytes[5] << 8) | Bytes[6]) / 1000.0 + valid_values = true + else + # Ignore other Fports + end #Fport + + if valid_values + if global.se01LNodes.find(Node) + global.se01LNodes.remove(Node) + end + # sensor[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] + global.se01LNodes.insert(Node, [Node, last_seen, battery_last_seen, battery, RSSI, temp, conductivity, moisture, dielectric, mod]) + end + + return data + end #decodeUplink() + + static def add_web_sensor() + var msg = "" + for sensor: global.se01LNodes + var name = string.format("SE01-L-%i", sensor[0]) + var name_tooltip = "Dragino SE01-L" + var last_seen = sensor[1] + var battery_last_seen = sensor[2] + var battery = sensor[3] + var rssi = sensor[4] + msg += lwdecode.header(name, name_tooltip, battery, battery_last_seen, rssi, last_seen) + + # Sensors + var temp = sensor[5] + var conductivity = sensor[6] + var moisture = sensor[7] + var dielectric = sensor[8] + var mod = sensor[9] + + msg += "