/* _____ _____ __ _ __ / ___/___ ____ ____ ___ ____ ___ ____ / ___/___ ____ _____/ /_(_)____/ /__ \__ \/ _ \/ __ \/_ / / _ \/ __ `__ \/ __ \\__ \/ _ \/ __ \/ ___/ __/ / ___/ //_/ ___/ / __/ / / / / /_/ __/ / / / / / /_/ /__/ / __/ / / (__ ) /_/ / /__/ ,< /____/\___/_/ /_/ /___/\___/_/ /_/ /_/\____/____/\___/_/ /_/____/\__/_/\___/_/|_| KOU20 HW 2.0 - FW 1.0 */ function decodeUplink(input) { const bytes = input.bytes || []; const port = input.fPort; function readInt16BE(data, index) { var value = (data[index] << 8) | data[index + 1]; if (value & 0x8000) { value -= 0x10000; } return value; } function readUint16BE(data, index) { return (data[index] << 8) | data[index + 1]; } function readUint24BE(data, index) { return (data[index] * 0x10000) | (data[index + 1] << 8) | data[index + 2]; } function result(data) { return { data: data, warnings: port == 4 ? ["RTT FIRMWARE"] : [], errors: [] }; } function error(message) { return { data: {}, warnings: port == 4 ? ["RTT FIRMWARE"] : [], errors: [message] }; } // Alarm packet - port 1 if (port == 1) { if (bytes.length != 1) { return error("Invalid alarm payload length: " + bytes.length + " bytes"); } return result({ Status: bytes[0] }); } // Data packet - release port 2, RTT/debug port 4 if (port == 2 || port == 4) { // Data packet without status if (bytes.length == 4) { return result({ Status: 0, Temperature: readInt16BE(bytes, 0) / 100, BatteryLevel: readUint16BE(bytes, 2) }); } // Data packet with status if (bytes.length == 5) { return result({ Status: bytes[0], Temperature: readInt16BE(bytes, 1) / 100, BatteryLevel: readUint16BE(bytes, 3) }); } // Data packet without status, with logging record if (bytes.length == 12) { return result({ Status: 0, Temperature: readInt16BE(bytes, 0) / 100, BatteryLevel: readUint16BE(bytes, 2), Logging: { FCnt: readUint24BE(bytes, 4), Status: bytes[7], Temperature: readInt16BE(bytes, 8) / 100, BatteryLevel: readUint16BE(bytes, 10) } }); } // Data packet with status and logging record if (bytes.length == 13) { return result({ Status: bytes[0], Temperature: readInt16BE(bytes, 1) / 100, BatteryLevel: readUint16BE(bytes, 3), Logging: { FCnt: readUint24BE(bytes, 5), Status: bytes[8], Temperature: readInt16BE(bytes, 9) / 100, BatteryLevel: readUint16BE(bytes, 11) } }); } return error("Invalid data payload length: " + bytes.length + " bytes"); } // Config packet - port 3 if (port == 3) { if (bytes.length != 9) { return error("Invalid config payload length: " + bytes.length + " bytes"); } const DataRatePlusADR = bytes[4]; return result({ Status: bytes[0], SendPeriod: bytes[1], MoveThr: bytes[2], PacketConfirm: bytes[3], DataRate: DataRatePlusADR & 0x0F, ADRon: Boolean(DataRatePlusADR & 0x80), FamilyId: bytes[5], ProductId: bytes[6], HW: bytes[7] / 10, FW: bytes[8] / 10 }); } return error("Unsupported FPort: " + port + ", payload length: " + bytes.length + " bytes"); }