// Decode decodes an array of bytes into an object. // - fPort contains the LoRaWAN fPort number // - bytes is an array of bytes, e.g. [225, 230, 255, 0] // - variables contains the device variables e.g. {"calibration": "3.5"} (both the key / value are of type string) // The function must return an object, e.g. {"temperature": 22.5} function Decode(fPort, data, variables) { if (fPort === 13) { return [ { led_state: bytes[0] === 0 ? "Off" : "On", mtm_code_1: bytes[1], mtm_code_2: bytes[2], hw_code: bytes[3], battery_level: bytes[4] + "%", size_value: bytes[5], spot_cnt: bytes[6] + " blocks", spillage_level: bytes[7] + "%", top1_position: "X= " + bytes[8] % 10 + " Y= " + parseFloat(bytes[8] / 10).toFixed(0), top2_position: "X= " + bytes[9] % 10 + " Y= " + parseFloat(bytes[9] / 10).toFixed(0), top3_position: "X= " + bytes[10] % 10 + " Y= " + parseFloat(bytes[10] / 10).toFixed(0), top4_position: "X= " + bytes[11] % 10 + " Y= " + parseFloat(bytes[11] / 10).toFixed(0), min_temp: (bytes[12] + bytes[13] / 100) + "C", average_temp: (bytes[14] + bytes[15] / 100) + "C", max_temp: (bytes[16] + bytes[17] / 100) + "C", center_temp: (bytes[18] + bytes[19] / 100) + "C", } ] } // Heart-beat port with LED state and remaining battery level % only else if (fPort === 14) { return [ { led_state: (bytes[0] & 0x7f) === 0 ? "Off" : "On", battery_level: bytes[1] + " %", } ]; } // fPort: 1, uplink of control command else if (fPort === 1) { // 0x56, report HW/SW version of node if (bytes[0] === 0x56) { return [ { mtm_code_1: bytes[1], mtm_code_2: bytes[2], HW_Version: "HW:" + bytes[3], SW_Version: "SW" + bytes[4] + ":" + bytes[5] + ":" + bytes[6] + ":" + bytes[7], } ]; } // 0x53, report seft testing result else if (bytes[0] === 0x53) { return [ { mtm_code_1: bytes[1], mtm_code_2: bytes[2], sw_code: bytes[3], hw_code: bytes[4], battery_level: bytes[5] + "%", size_value: bytes[6], average_temp: (bytes[7] + bytes[8] / 100) + "C", center_temp: (bytes[9] + bytes[10] / 100) + "C", min_temp: (bytes[11] + bytes[12] / 100) + "C", max_temp: (bytes[13] + bytes[14] / 100) + "C", } ]; } // 0x43, report config of node else if (bytes[0] === 0x43) { return [ { mtm_code_1: bytes[1], mtm_code_2: bytes[2], sw_code: bytes[3], hw_code: bytes[4], uplink: bytes[5], uplink_unit: bytes[6], heart_beat_interval: bytes[7], heart_beat_interval_unit: bytes[8], work_mode: bytes[9], service_mask: bytes[10], size_value: bytes[12], // key parameters averageTempThreshold: (bytes[14]) + " C", // emmisivity for water 0.96, human 0.92 emmisivityThreshold: (bytes[16] / 100), humanTempThreshold: (bytes[18]) + " C", waterTempThreshold: (bytes[20] / 10) + " C", } ]; } // 0x59,0x44 report configed heart-beat interval if (bytes[0] === 0x59) { if (bytes[1] === 0x53) { return [ { Type: "Heart Beat Interval", HB_interval: (bytes[2] - 0x30) * 10 + (bytes[3] - 0x30), HB_interval_unit: String.fromCharCode(bytes[4]), } ]; } else if (bytes[1] === 0x44) { return [ { Type: "Periodic Upload Interval", Upload_interval: (bytes[2] - 0x30) * 10 + (bytes[3] - 0x30), Upload_interval_unit: String.fromCharCode(bytes[4]), } ]; } } } };