v4.17 JS Decode Error after update from v4.16

Viewed 16

I have a few devices which are not decoding correctly now since my console has been updated to v4.17 last week.

One i have noticed is the merry iot open/close sensor, chirpstack with quickjs now throws a Code: UPLINK_CODEC Level: ERROR for it now stating "JS error: Error: battery_volt is not defined at decodeUplink (main:61:23) at <anonymous> (main:118:37)"

on testing the decoder and payload bytes it decodes fine as expected.

I have attached example of previous working code and decoder for reference which in chirpstack gives above error now.

////////////* MerryIot Open/Close sensor*////////////

//hex to binary function
function hex2bin(hex){
  return (parseInt(hex, 16).toString(2)).padStart(8, '0');
}

//MerryIot Open/Close sensor
function decodeUplink(input) {
	let fPort = input.fPort;
	let payloadlens = input.bytes.length;
	if(fPort==120 && payloadlens==10){
		let intput_list = input.bytes;
		let battery_int=intput_list[1];// battery calculate
		battery_volt = (21+battery_int)/10;
		temperature_hex= (intput_list[3].toString(16).padStart(2, '0'))+(intput_list[2].toString(16).padStart(2, '0'));  //temperature calculate
		if((parseInt(temperature_hex, 16))>1250){
			temperature = ((parseInt(temperature_hex, 16))-65536)/10;
		}
		else{
			temperature = (parseInt(temperature_hex, 16))/10;
		}
		humi =  intput_list[4]; //Humidity calculate
		let door_hex = intput_list[0].toString(16).padStart(2, '0'); // Sensor Status calculate
		let door_binary = hex2bin(door_hex);
		let open_st = door_binary.substring(7, 8);
		let button_st = door_binary.substring(6, 7);
		let tamper_st = door_binary.substring(5, 6);
		let tilt_st = door_binary.substring(4, 5);

		open = parseInt(open_st); // Door status
		button = parseInt(button_st); // Button pressed
		tamper = parseInt(tamper_st); // Tamper detected
		tilt = parseInt(tilt_st); // Tilt detected

		let time_hex = (intput_list[6].toString(16).padStart(2, '0'))+(intput_list[5].toString(16).padStart(2, '0'));
		time = parseInt(time_hex, 16); //Time elapsed since last event trigger
		let count_hex = (intput_list[9].toString(16).padStart(2, '0'))+(intput_list[8].toString(16))+(intput_list[7].toString(16).padStart(2, '0'));
		count = parseInt(count_hex, 16); //Total count of event triggers

		return {
			data: {
				battery_volt,
				temperature,
				humi,
				open,
				button,
				tamper,
				tilt,
				time,
				count
			},
		};
  }
  else if (fPort==120 && payloadlens==9){
			let intput_list = input.bytes;
			let battery_int=intput_list[1];// battery calculate
			battery_volt = (21+battery_int)/10;
			temperature_int= intput_list[2]; //temperature calculate
			if(temperature_int>125){
				temperature = temperature_int-256;
			}
			else{
				temperature = temperature_int;
			}
			humi =  intput_list[3]; //Humidity calculate
			let door_hex = intput_list[0].toString(16).padStart(2, '0'); // Sensor Status calculate
			let door_binary = hex2bin(door_hex);
			let open_st = door_binary.substring(7, 8);
			let button_st = door_binary.substring(6, 7);
			let tamper_st = door_binary.substring(5, 6);
			let tilt_st = door_binary.substring(4, 5);

			open = parseInt(open_st); // Door status
			button = parseInt(button_st); // Button pressed
			tamper = parseInt(tamper_st); // Tamper detected
			tilt = parseInt(tilt_st); // Tilt detected

			let time_hex = (intput_list[5].toString(16).padStart(2, '0'))+(intput_list[4].toString(16).padStart(2, '0'));
			time = parseInt(time_hex, 16); //Time elapsed since last event trigger
			let count_hex = (intput_list[8].toString(16).padStart(2, '0'))+(intput_list[7].toString(16).padStart(2, '0'))+(intput_list[6].toString(16).padStart(2, '0'));
			count = parseInt(count_hex, 16); //Total count of event triggers

			return {
				data: {
					battery_volt,
					temperature,
					humi,
					open,
					button,
					tamper,
					tilt,
					time,
					count
				},
			};
	}
  else{
		let fPort = input.fPort;
		let payloadlength = input.bytes.length;
		let message = 'Invalid fPort or payload length';
		return {
			data: {
			fPort,
			payloadlength,
			message,
			},
		};
	}
}

////////////* MerryIot Open/Close sensor End !!*////////////

const buf = Buffer.from('AA8bJQAASCUA', 'base64')
input = { bytes: buf, fPort: 120 }
console.log(decodeUplink(input))

Expected output

{
  data: {
    battery_volt: 3.6,
    temperature: 27,
    humi: 37,
    open: 0,
    button: 0,
    tamper: 0,
    tilt: 0,
    time: 0,
    count: 9544
  }
}
2 Answers

You should probably change:

battery_volt = (21+battery_int)/10;

to:

let battery_volt = (21+battery_int)/10;

You are assigning a value to battery_volt, which is not defined in the code (as far as I can see), which is why you see this error.

This is related to the bugfixes in:
https://www.chirpstack.io/docs/chirpstack/changelog.html#bugfixes

Fix JS codec / Buffer module unable to import ieee754 module.

There was an issue with the original JS codec implementation and how the buffer and ieee754 modules were injected. Both modules were visible to the codec functions, however the buffer module failed to import the ieee754 module. https://github.com/chirpstack/chirpstack/commit/2d571f28a5668ca82486bd55d2406f0e2d9d4441 properly fixes this, however it is no longer possible to disable the strict mode. This means that you can no longer assign values to an undefined variable.

Thanks mate, that shed some light on the issue.

I redone all the device codecs for the ones my end i seen that were being effected - all browan/merryiot using there official decoders.

I will check them for any further errors over the next few days and push changes to device profiles repo as well if all is well.