"CODEC","error":"execution timeout"


#1

Dear All,

I’m running the latest version of Loraserver, and from time to time, I’m getting error message reported as :
application/2/device/deveui/error

with the following error message in the payload : “CODEC”,“error”:“execution timeout”

most go the time, messages are properly decoded and this error occur randomly

Any suggestion
Thanks in advance for your help


#2

What device and codec do you use ?


#3

I’m using my own device and a custom codec, codec is working properly, but from time to time, I’m having and execution timeout error, this is related to the following :

// CodecMaxExecTime holds the max. time the (custom) codec is allowed to
// run.
var CodecMaxExecTime = 10 * time.Millisecond

into the custom_js.go file


#4

If one of you would like to contribute with a pull-request, this would be fairly easy to move to the configuration file :slight_smile:


#5

I’m not too familiar with this SW and not sure to be able to make such pull-request, if someone can help and train me that would be appreciated :slight_smile:


#6

Anyway, I would be surprised that this small piece of decode function would take more than 10ms to execute on a quad core running at 1.2 Ghz with 2G of DDR :slight_smile:
function Decode(fPort, bytes) {
var decoded = {};
decoded.cmd = bytes[0];
if (decoded.cmd === 16 || decoded.cmd === 32 || decoded.cmd === 48)
{
decoded.hours = bytes[1];
decoded.minutes = bytes[2];

	var index = 4;
	var pair = true;
	var header = bytes[3];

	if (header & 0x80)
	{
		decoded.pio0Event = bytes[index];
		index += 1;
	}
	if (header & 0x40)
	{
		decoded.pio1Event = bytes[index];
		index += 1;
	}
	if (header & 0x20)
	{
		if (pair )
		{
			decoded.pio2Event = (bytes[index]*16 + (bytes[index+1] & 0xF0)/16);
			index += 1;
			pair = false;
		} else {
			decoded.pio2Event = (bytes[index+1] + (bytes[index] & 0x0F)*256);
			index += 2;
			pair = true;
		}
	}
	if (header & 0x10)
	{
		if (pair )
		{
			decoded.pio3Event = (bytes[index]*16 + (bytes[index+1] & 0xF0)/16);
			index += 1;
			pair = false;
		} else {
			decoded.pio3Event = (bytes[index+1] + (bytes[index] & 0x0F)*256);
			index += 2;
			pair = true;
		}
	}
	if (header & 0x08)
	{
		if (pair )
		{
			decoded.intTemp = ((bytes[index]*16 + (bytes[index+1] & 0xF0)/16)/16);
			index += 1;
			pair = false;
		} else {
			decoded.intTemp = ((bytes[index+1] + (bytes[index] & 0x0F)*256)/16);
			index += 2;
			pair = true;
		}
	}
	if (header & 0x04)
	{
		if (pair )
		{
			decoded.extTemp = (bytes[index]*16 + (bytes[index+1] & 0xF0)/16);
			index += 1;
			pair = false;
		} else {
			decoded.extTemp = (bytes[index+1] + (bytes[index] & 0x0F)*256);
			index += 2;
			pair = true;
		}
	}
	if (header & 0x02)
	{
		if (pair )
		{
			decoded.Vbat = (bytes[index]*16 + (bytes[index+1] & 0xF0)/16);
			index += 1;
			pair = false;
		} else {
			decoded.Vbat = (bytes[index+1] + (bytes[index] & 0x0F)*256);
			index += 2;
			pair = true;
		}
	}
	if (header & 0x01)
	{
		if (pair )
		{
			decoded.Vext = (bytes[index]*16 + (bytes[index+1] & 0xF0)/16);
			index += 1;
			pair = false;
		} else {
			decoded.Vext = (bytes[index+1] + (bytes[index] & 0x0F)*256);
			index += 2;
			pair = true;
		}
	}
	
}
if (decoded.cmd === 00)
{
	decoded.config_exist = bytes[1];
	decoded.hours = bytes[2];
	decoded.minutes = bytes[3];
	decoded.guardTimeDay = bytes[4];
	decoded.guardTimeNight = bytes[5];
	decoded.KeepAliveValue = bytes[6];
	decoded.pio0EventThresholdDay = bytes[7]; 
	decoded.pio0EventThresholdNight = bytes[8];
	decoded.pio1EventThresholdDay =bytes[9];
	decoded.pio1EventThresholdNight = bytes[10];
	decoded.pio2EventThresholdDay = (bytes[11]*16 + (bytes[12] & 0xF0)/16);
	decoded.pio2EventThresholdNight = (bytes[13] + (bytes[12] & 0x0F)*256);
	decoded.pio3EventThresholdDay = (bytes[14]*16 + (bytes[15] & 0xF0)/16);
	decoded.pio3EventThresholdNight = (bytes[16] + (bytes[15] & 0x0F)*256);
	decoded.nightStartHours = bytes[17];
	decoded.nightStartMinutes = bytes[18];
	decoded.dayStartHours = bytes[19];
	decoded.dayStartMinutes = bytes[20];
	decoded.en_Register = bytes[21];
}
return decoded;

}


#7

Anyone can help me how to contribute with a pull request ?
Thanks in advance


#8

Did anybody experienced this CODEC execution time out ?
I’ve made tests with a “smaller” codec and do not see anymore time out.


#9

When installing from scratch the 2.X version, I have no CODEC execution time out,
When upgrading from 1.X to 2.X :

  • uninstall lora-app-server
  • uninstall loraserver
  • uninstall lora-gateway-bridge
    then installing the 3 packages V2.X, all is working fine, but having from time to time CODEC execution time out

#10

Well, I’ve experienced same behavior. Some frames are no decoded due to “execution timeout”.

// 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]
// The function must return an object, e.g. {"temperature": 22.5}
function Decode(fPort, bytes) {
	function timestamp_generator(secondsTakenOff) {
    	var date = new Date();
        date.setUTCSeconds(date.getUTCSeconds() - secondsTakenOff);
        return date.toISOString();
    } 
	
	var header = bytes[0] >> 6;
	
	switch(header) {
		case 0:
			pressure = (bytes[0] & 63) << 6 | bytes[1] >> 2;
			humidity = (bytes[1] & 3) << 5 | bytes[2] >> 3;
			height_1 = (bytes[2] & 7) << 9 | bytes[3] << 1 | bytes[4] >> 7;
			height_1_delta_1 = (bytes[4] & 127) << 1 | bytes[5] >> 7;
			height_2 = (bytes[5] & 127) << 5 | bytes[6] >> 3;
			height_2_delta_2 = (bytes[6] & 7) << 5 | bytes[7] >> 3;
			temperature = (bytes[7] & 7) << 7 | bytes[8] >> 1;
			temperature_delta_1 = (bytes[8] & 1) << 7 | bytes[9] >> 1;
			temperature_delta_2 = (bytes[9] & 1) << 7 | bytes[10] >> 1;
			temperature_delta_3 = (bytes[10] & 1) << 7 | bytes[11] >> 1;
			return {"frameType":"mesure", "pressure":{"value": pressure, "timestamp": timestamp_generator(0)}, "humidity":{"value":humidity, "timestamp": timestamp_generator(0)}, "height_1":{"value": height_1, "timestamp": timestamp_generator(0)}, "height_1_delta_1":{"value": height_1_delta_1, "timestamp":timestamp_generator(225)}, "height_2":{"value": height_2, "timestamp": timestamp_generator(450)}, "height_2_delta_2":{"value": height_2_delta_2, "timestamp": timestamp_generator(675)}, "temperature":{"value":temperature, "timestamp":timestamp_generator(0)}, "temperature_delta_1":{"value": temperature_delta_1, "timestamp":timestamp_generator(225)}, "temperature_delta_2":{"value": temperature_delta_2, "timestamp": timestamp_generator(450)}, "temperature_delta_3":{"value": temperature_delta_3, "timestamp": timestamp_generator(675)}};
		case 1:
			pressure = (bytes[0] & 63) << 6 | bytes[1] >> 2;
			humidity = (bytes[1] & 3) << 5 | bytes[2] >> 3;
			temperature = (bytes[2] & 7) << 7 | bytes[3] >> 1;
			battery = (bytes[3] & 1) << 9 | bytes[4] << 1 | bytes[5] >> 7;
			accelerometer_X = (bytes[5] & 126);
			accelerometer_Y = (bytes[5] & 1) << 5 | bytes[6] >> 3;
			accelerometer_Z = (bytes[6] & 7) << 3 | bytes[7] >> 5;
			return {"frameType":"status", "pressure":{"value": pressure, "timestamp":timestamp_generator(0)}, "humidity":{"value": humidity, "timestamp":timestamp_generator(0)}, "temperature":{"value": temperature, "timestamp":timestamp_generator(0)}, "battery":{"value": battery, "timestamp":timestamp_generator(0)}, "accelerometer_X":{"value": accelerometer_X, "timestamp":timestamp_generator(0)}, "accelerometer_Y":{"value": accelerometer_Y, "timestamp":timestamp_generator(0)}, "accelerometer_Z":{"value": accelerometer_Z, "timestamp":timestamp_generator(0)}};
		case 2:
			pressure = (bytes[0] & 63) << 6 | bytes[1] >> 2;
			humidity = (bytes[1] & 3) << 5 | bytes[2] >> 3;
			temperature = (bytes[2] & 7) << 7 | bytes[3] >> 1;
			battery = (bytes[3] & 1) << 9 | bytes[4] << 1 | bytes[5] >> 7;
			accelerometer_X = (bytes[5] & 126);
			accelerometer_Y = (bytes[5] & 1) << 5 | bytes[6] >> 3;
			accelerometer_Z = (bytes[6] & 7) << 3 | bytes[7] >> 5;
			height_1 = (bytes[7] & 31) << 7 | bytes[8] >> 1;
			return {"frameType":"status", "pressure":{"value": pressure, "timestamp":timestamp_generator(0)}, "humidity":{"value": humidity, "timestamp":timestamp_generator(0)}, "temperature":{"value": temperature, "timestamp":timestamp_generator(0)}, "battery":{"value": battery, "timestamp":timestamp_generator(0)}, "accelerometer_X":{"value": accelerometer_X, "timestamp":timestamp_generator(0)}, "accelerometer_Y":{"value": accelerometer_Y, "timestamp":timestamp_generator(0)}, "accelerometer_Z":{"value": accelerometer_Z, "timestamp":timestamp_generator(0)}, "height_1":{"value": height_1, "timestamp":timestamp_generator(0)}};
	}
}

I can’t reinstall from scratch.

BTW, in my return “case 0”, I take several time the current time. And it varies from 0 to 3 milliseconds. So my entire code could actually run in more than 10 ms. Is there a reason to limit the decoding to 10 ms ?

PS : @brocaar what do you want from us to Pull-request ?