diff --git a/vendors/dragino/codecs/t68dl.js b/vendors/dragino/codecs/t68dl.js new file mode 100644 index 0000000..73a8c4a --- /dev/null +++ b/vendors/dragino/codecs/t68dl.js @@ -0,0 +1,136 @@ +// Based on the official Dragino T68DL v1.0 decoder: +// https://github.com/dragino/dragino-end-node-decoder/blob/main/T68DL/T68DL_v1.0_decoder.txt +// Payload documentation: +// https://wiki.dragino.com/docs/LoRaWAN-End-Node/temperature-humidity-sensors/t68dl/ +function decodeUplink(input) { + var bytes = input.bytes; + var data = {}; + + function datalog(i, bytes) { + var aa = parseFloat( + ((((bytes[4 + i] << 24) >> 16) | bytes[5 + i]) / 100).toFixed(2) + ); + var bb = getMyDate( + ( + (bytes[7 + i] << 24) | + (bytes[8 + i] << 16) | + (bytes[9 + i] << 8) | + bytes[10 + i] + ).toString(10) + ); + var string = "[" + aa + "," + bb + "]" + ","; + + return string; + } + + function getzf(c_num) { + if (parseInt(c_num) < 10) c_num = "0" + c_num; + + return c_num; + } + + function getMyDate(str) { + var c_Date; + if (str > 9999999999) c_Date = new Date(parseInt(str)); + else c_Date = new Date(parseInt(str) * 1000); + + var c_Year = c_Date.getFullYear(), + c_Month = c_Date.getMonth() + 1, + c_Day = c_Date.getDate(), + c_Hour = c_Date.getHours(), + c_Min = c_Date.getMinutes(), + c_Sen = c_Date.getSeconds(); + var c_Time = + c_Year + + "-" + + getzf(c_Month) + + "-" + + getzf(c_Day) + + " " + + getzf(c_Hour) + + ":" + + getzf(c_Min) + + ":" + + getzf(c_Sen); + + return c_Time; + } + + switch (input.fPort) { + case 2: + data.BatV = ((bytes[0] << 8) | bytes[1]) / 1000; + data.TempC = parseFloat( + ((((bytes[2] << 24) >> 16) | bytes[3]) / 100).toFixed(2) + ); + data.TEMPH_flag = bytes[4] & 0x01 ? "True" : "False"; + data.TEMPL_flag = bytes[4] & 0x02 ? "True" : "False"; + data.Data_time = getMyDate( + ( + (bytes[5] << 24) | + (bytes[6] << 16) | + (bytes[7] << 8) | + bytes[8] + ).toString(10) + ); + data.Node_type = "T68DL"; + + if (bytes.length == 9) + return { + data: data, + }; + break; + + case 3: + var pnack = (bytes[6] >> 7) & 0x01 ? "True" : "False"; + var data_sum = ""; + for (var i = 0; i < bytes.length; i = i + 11) { + var data1 = datalog(i, bytes); + if (i == "0") data_sum = data1; + else data_sum += data1; + } + data.Node_type = "T68DL"; + data.DATALOG = data_sum; + data.PNACKMD = pnack; + return { + data: data, + }; + + case 5: + if (bytes[0] == 0x34) data.SENSOR_MODEL = "T68DL"; + + if (bytes[4] == 0xff) data.SUB_BAND = "NULL"; + else data.SUB_BAND = bytes[4]; + + if (bytes[3] == 0x01) data.FREQUENCY_BAND = "EU868"; + else if (bytes[3] == 0x02) data.FREQUENCY_BAND = "US915"; + else if (bytes[3] == 0x03) data.FREQUENCY_BAND = "IN865"; + else if (bytes[3] == 0x04) data.FREQUENCY_BAND = "AU915"; + else if (bytes[3] == 0x05) data.FREQUENCY_BAND = "KZ865"; + else if (bytes[3] == 0x06) data.FREQUENCY_BAND = "RU864"; + else if (bytes[3] == 0x07) data.FREQUENCY_BAND = "AS923"; + else if (bytes[3] == 0x08) data.FREQUENCY_BAND = "AS923_1"; + else if (bytes[3] == 0x09) data.FREQUENCY_BAND = "AS923_2"; + else if (bytes[3] == 0x0a) data.FREQUENCY_BAND = "AS923_3"; + else if (bytes[3] == 0x0b) data.FREQUENCY_BAND = "CN470"; + else if (bytes[3] == 0x0c) data.FREQUENCY_BAND = "EU433"; + else if (bytes[3] == 0x0d) data.FREQUENCY_BAND = "KR920"; + else if (bytes[3] == 0x0e) data.FREQUENCY_BAND = "MA869"; + + data.FIRMWARE_VERSION = + (bytes[1] & 0x0f) + + "." + + ((bytes[2] >> 4) & 0x0f) + + "." + + (bytes[2] & 0x0f); + data.BAT = ((bytes[5] << 8) | bytes[6]) / 1000; + + return { + data: data, + }; + + default: + return { + errors: ["unknown FPort"], + }; + } +} diff --git a/vendors/dragino/codecs/test_decode_t68dl.json b/vendors/dragino/codecs/test_decode_t68dl.json new file mode 100644 index 0000000..6b562fa --- /dev/null +++ b/vendors/dragino/codecs/test_decode_t68dl.json @@ -0,0 +1,66 @@ +[ + { + "name": "Test decode Dragino T68DL real-time data (fPort 2)", + "input": { + "fPort": 2, + "bytes": [14, 28, 9, 246, 0, 101, 83, 241, 0] + }, + "expected": { + "data": { + "BatV": 3.612, + "TempC": 25.5, + "TEMPH_flag": "False", + "TEMPL_flag": "False", + "Data_time": "2023-11-14 22:13:20", + "Node_type": "T68DL" + } + } + }, + { + "name": "Test decode Dragino T68DL negative temperature with alarm flag (fPort 2)", + "input": { + "fPort": 2, + "bytes": [14, 28, 253, 238, 2, 101, 83, 241, 0] + }, + "expected": { + "data": { + "BatV": 3.612, + "TempC": -5.3, + "TEMPH_flag": "False", + "TEMPL_flag": "True", + "Data_time": "2023-11-14 22:13:20", + "Node_type": "T68DL" + } + } + }, + { + "name": "Test decode Dragino T68DL datalog (fPort 3)", + "input": { + "fPort": 3, + "bytes": [0, 0, 0, 0, 9, 246, 0, 101, 83, 241, 0] + }, + "expected": { + "data": { + "Node_type": "T68DL", + "DATALOG": "[25.5,2023-11-14 22:13:20],", + "PNACKMD": "False" + } + } + }, + { + "name": "Test decode Dragino T68DL device status (fPort 5)", + "input": { + "fPort": 5, + "bytes": [52, 1, 0, 1, 255, 14, 28] + }, + "expected": { + "data": { + "SENSOR_MODEL": "T68DL", + "SUB_BAND": "NULL", + "FREQUENCY_BAND": "EU868", + "FIRMWARE_VERSION": "1.0.0", + "BAT": 3.612 + } + } + } +] diff --git a/vendors/dragino/codecs/test_encode_t68dl.json b/vendors/dragino/codecs/test_encode_t68dl.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/vendors/dragino/codecs/test_encode_t68dl.json @@ -0,0 +1 @@ +[] diff --git a/vendors/dragino/devices/t68dl.toml b/vendors/dragino/devices/t68dl.toml new file mode 100644 index 0000000..2f892a7 --- /dev/null +++ b/vendors/dragino/devices/t68dl.toml @@ -0,0 +1,18 @@ +[device] +id = "818138c6-9e6a-4562-a997-97a4e5110e0e" +name = "T68DL" +description = "Long range LoRaWAN temperature sensor with built-in TMP117 high-accuracy sensor and datalog feature." + +[[device.firmware]] +version = "1.0.0" +profiles = [ + "AS923-1_0_3.toml", + "AU915-1_0_3.toml", + "EU868-1_0_3.toml", + "US915-1_0_3.toml", +] +codec = "t68dl.js" + +[device.metadata] +product_url = "https://www.dragino.com/products/temperature-humidity-sensor/item/352-t68dl.html" +documentation_url = "https://wiki.dragino.com/docs/LoRaWAN-End-Node/temperature-humidity-sensors/t68dl/" diff --git a/vendors/dragino/profiles/AU915-1_0_3-CLASS_C.toml b/vendors/dragino/profiles/AU915-1_0_3-CLASS_C.toml index eb8f03d..06b7ec6 100644 --- a/vendors/dragino/profiles/AU915-1_0_3-CLASS_C.toml +++ b/vendors/dragino/profiles/AU915-1_0_3-CLASS_C.toml @@ -2,7 +2,7 @@ id = "5212951d-10f2-4a3a-bd6f-1033cc70b96f" vendor_profile_id = 0 region = "AU915" -mac_version = "1.0.0" +mac_version = "1.0.3" reg_params_revision = "A" supports_otaa = true supports_class_b = false diff --git a/vendors/dragino/profiles/EU868-1_0_3.toml b/vendors/dragino/profiles/EU868-1_0_3.toml index 7196814..d2a2e8b 100644 --- a/vendors/dragino/profiles/EU868-1_0_3.toml +++ b/vendors/dragino/profiles/EU868-1_0_3.toml @@ -2,7 +2,7 @@ id = "3220e39c-edaf-4293-abfb-891a66c6e877" vendor_profile_id = 0 region = "EU868" -mac_version = "1.0.0" +mac_version = "1.0.3" reg_params_revision = "A" supports_otaa = true supports_class_b = false diff --git a/vendors/dragino/vendor.toml b/vendors/dragino/vendor.toml index 45222d4..de1833b 100644 --- a/vendors/dragino/vendor.toml +++ b/vendors/dragino/vendor.toml @@ -9,6 +9,7 @@ devices = [ "lds02.toml", "ldds75.toml", "lht65n.toml", + "t68dl.toml", ] [vendor.metadata]