⬆️Flood Sensor Uplink Decoder

Universal Decoder:

Supports: The Thinks Network, Milesight, DataCake, Chirpstack

// DataCake
function Decoder(bytes, port){
    var decoded = decodeUplink({ bytes: bytes, fPort: port }).data;
    return decoded;
}

// Milesight
function Decode(port, bytes){
    var decoded = decodeUplink({ bytes: bytes, fPort: port }).data;
    return decoded;
}

// The Things Industries / Main
function decodeUplink(input) {
	var bytes = input.bytes;
	var data = {};
	var decbin = function (number) {
		return parseInt(number, 10).toString(2);
	};
	var byteArray = bytes.map(function (byte) {
		var number = decbin(byte);
		return Array(9 - number.length).join('0') + number;
	});
	var messageTypes = ['keepalive', 'testButtonPressed', 'floodDetected', 'fraudDetected','fraudDetected'];
	function toBool(value) {
		return value == '1';
	};
	function handleKeepAliveData(byteArray, data) {
		var shortPackage = function (byteArray, data) {
			data.reason = messageTypes[parseInt(byteArray[0].slice(0, 3), 2)];
			data.boxTamper = toBool(byteArray[0][4]);
			data.flood = toBool(byteArray[0][6]);
			data.battery = (parseInt(byteArray[1], 2) * 16) / 1000;
			return data
		};
		var longPackage = function (byteArray, data) {
				data.reason = messageTypes[parseInt(byteArray[0].slice(0, 3), 2)];
				data.boxTamper = toBool(byteArray[0][4]);
				data.flood = toBool(byteArray[0][6]);
				data.battery = (parseInt(byteArray[1], 2) * 16) / 1000;
				data.temperature = parseInt(byteArray[2], 2);
			return data
		};

		if (byteArray.length > 2) {
			return longPackage(byteArray,data);
		} else {
			return shortPackage(byteArray,data);
		}
	}


	function handleResponse(bytes, data) {
		var commands = bytes.map(function (byte) {
			return ("0" + byte.toString(16)).substr(-2);
		});
		commands = commands.slice(0, -3);
		var command_len = 0;

		commands.map(function (command, i) {
			switch (command) {
				case '06':
					{
					command_len = 1;
					data.alarmDuration = parseInt(commands[i + 1], 16) ;
					}
				break;
				case '07':
            		{
                    // console.log(hexData)
						command_len = 2;
						var hardwareVersion = commands[i + 1];
						var softwareVersion = commands[i + 2];
						data.deviceVersions = { 'hardware': Number(hardwareVersion), 'software': Number(softwareVersion) } ;
            		}
            		break;
				case '09':
					{
						command_len = 1;
						data.floodEventSendTime = parseInt(commands[i + 1], 16) ;
					}
				break;
				case '12':
					{
						command_len = 2;
						data.keepAliveTime = parseInt(commands[i + 1] + commands[i + 2], 16);
					}
					break;
				case '19':
					{
						command_len = 1;
						var commandResponse = parseInt(commands[i + 1], 16);
						var periodInMinutes = commandResponse * 5 / 60;
						data.joinRetryPeriod = periodInMinutes;
					}
					break;
				case '1b':
					{
						command_len = 1;
						data.uplinkType = parseInt(commands[i + 1], 16);
					}
					break;
				case '1d':
					{
						command_len = 2;
						var wdpC = commands[i + 1] == '00' ? false : parseInt(commands[i + 1], 16);
						var wdpUc = commands[i + 2] == '00' ? false : parseInt(commands[i + 2], 16);
						data.watchDogParams = { 'wdpC': wdpC, 'wdpUc': wdpUc };
					}
					break;


				default:
					break;
			}
			commands.splice(i, command_len);
		});
		return data;
	}

	if (byteArray.length <= 3) {
		data = handleKeepAliveData(byteArray, data);
	} else {
		data = handleResponse(bytes, data);
		byteArray = byteArray.slice(-3);
		data = handleKeepAliveData(byteArray, data);
	}
	return { data: data };
}

Last updated

Was this helpful?