varhistoryData={};vardecoded={};decoded.hexString=bytesToHex(input);for(vari=0;i<input.length;){varchannel_id=input[i];varchannel_type=input[i+1];i+=2;// PROTOCOL VERSIONif(channel_id==-1&&channel_type==1){decoded.protocol_version=input[i];i+=1;}// SERIAL NUMBERelseif(channel_id==-1&&channel_type==8){vartemp=[];varlast_index_sn=i+6;for(varidxsn=i;idxsn<last_index_sn;idxsn++){temp.push(bytesToHex([input[idxsn]&0xff]));}decoded.serialNumber=temp.join("");i+=6;}// HARDWARE VERSIONelseif(channel_id==-1&&channel_type==9){vartemphv=[];varlast_index_hv=i+2;for(varidxhv=i;idxhv<last_index_hv;idxhv++){temphv.push((input[idxhv]&0xff).toString());}decoded.hardwareVersion=temphv.join(".");i+=2;}// FIRMWARE VERSIONelseif(channel_id==-1&&channel_type==31){vartempfv=[];varlast_index_fv=i+4;for(varidxfv=i;idxfv<last_index_fv;idxfv++){tempfv.push((input[idxfv]&0xff).toString());}decoded.firmwareVersion=tempfv.join(".");i+=4;}// PEOPLE COUNTERelseif(channel_id==4&&channel_type==-55){decoded.peopleCountAll=input[i];decoded.regionCount=input[i+1];varregion=parseBytesToInt(input,i+2,2,false);for(varidxpc=0;idxpc<decoded.regionCount;idxpc++){vartmp="region"+(idxpc+1);decoded[tmp]=(region>>idxpc)&1;}i+=4;}// PEOPLE IN/OUTelseif(channel_id==5&&channel_type==-52){decoded.peopleIn=parseBytesToInt(input,i,2,false);decoded.peopleOut=parseBytesToInt(input,i+2,2,false);i+=4;}// PEOPLE MAXelseif(channel_id==6&&channel_type==-51){decoded.peopleCountMax=input[i];i+=1;}// REGION COUNTERelseif(channel_id==7&&channel_type==-43){decoded.region1Count=input[i];decoded.region2Count=input[i+1];decoded.region3Count=input[i+2];decoded.region4Count=input[i+3];decoded.region5Count=input[i+4];decoded.region6Count=input[i+5];decoded.region7Count=input[i+6];decoded.region8Count=input[i+7];i+=8;}// REGION COUNTERelseif(channel_id==8&&channel_type==-43){decoded.region9Count=input[i];decoded.region10Count=input[i+1];decoded.region11Count=input[i+2];decoded.region12Count=input[i+3];decoded.region13Count=input[i+4];decoded.region14Count=input[i+5];decoded.region15Count=input[i+6];decoded.region16Count=input[i+7];i+=8;}// A FLOWelseif(channel_id==9&&channel_type==-38){decoded.aToA=parseBytesToInt(input,i,2,false);decoded.aToB=parseBytesToInt(input,i+2,2,false);decoded.aToC=parseBytesToInt(input,i+4,2,false);decoded.aToD=parseBytesToInt(input,i+6,2,false);i+=8;}// B FLOWelseif(channel_id==10&&channel_type==-38){decoded.bToA=parseBytesToInt(input,i,2,false);decoded.bToB=parseBytesToInt(input,i+2,2,false);decoded.bToC=parseBytesToInt(input,i+4,2,false);decoded.bToD=parseBytesToInt(input,i+6,2,false);i+=8;}// C FLOWelseif(channel_id==11&&channel_type==-38){decoded.cToA=parseBytesToInt(input,i,2,false);decoded.cToB=parseBytesToInt(input,i+2,2,false);decoded.cToC=parseBytesToInt(input,i+4,2,false);decoded.cToD=parseBytesToInt(input,i+6,2,false);i+=8;}// D FLOWelseif(channel_id==12&&channel_type==-38){decoded.dToA=parseBytesToInt(input,i,2,false);decoded.dToB=parseBytesToInt(input,i+2,2,false);decoded.dToC=parseBytesToInt(input,i+4,2,false);decoded.dToD=parseBytesToInt(input,i+6,2,false);i+=8;}// TOTAL IN/OUTelseif(channel_id==13&&channel_type==-52){decoded.peopleTotalIn=parseBytesToInt(input,i,2,false);decoded.peopleTotalOut=parseBytesToInt(input,i+2,2,false);i+=4;}// DWELL TIMEelseif(channel_id==14&&channel_type==-28){varregion1=input[i];decoded.region=region1;decoded.dwellTimeAvg=parseBytesToInt(input,i+1,2,false);decoded.dwellTimeMax=parseBytesToInt(input,i+3,2,false);i+=5;}// TIMESTAMPelseif(channel_id==15&&channel_type==-123){decoded.timestamp=parseBytesToInt(input,i,4,false);i+=4;}else{break;}}output.telemetry=decoded;
vardata=decodeToJson(payload);vardeviceName=data.deviceInfo.deviceName;vardeviceType=data.deviceInfo.deviceProfileName;// var groupName = 'IAQ devices';// var customerName = 'Customer A';// use assetName and assetType instead of deviceName and deviceType// to automatically create assets instead of devices.// var assetName = 'Asset A';// var assetType = 'building';// If you want to parse incoming data somehow, you can add your code to this function.// input: bytes// expected output:// {// "attributes": {"attributeKey": "attributeValue"},// "telemetry": {"telemetryKey": "telemetryValue"}// }//// In the example - bytes will be saved as HEX string and also parsed as light level, battery level and PIR sensor value.//functiondecodePayload(input){varoutput={attributes:{},telemetry:{}};// --- Decoding code --- //output.telemetry.HEX_bytes=bytesToHex(input);varhistoryData={};vardecoded={};decoded.hexString=bytesToHex(input);for(vari=0;i<input.length;){varchannel_id=input[i];varchannel_type=input[i+1];i+=2;// PROTOCOL VERSIONif(channel_id==-1&&channel_type==1){decoded.protocol_version=input[i];i+=1;}// SERIAL NUMBERelseif(channel_id==-1&&channel_type==8){vartemp=[];varlast_index_sn=i+6;for(varidxsn=i;idxsn<last_index_sn;idxsn++){temp.push(bytesToHex([input[idxsn]&0xff]));}decoded.serialNumber=temp.join("");i+=6;}// HARDWARE VERSIONelseif(channel_id==-1&&channel_type==9){vartemphv=[];varlast_index_hv=i+2;for(varidxhv=i;idxhv<last_index_hv;idxhv++){temphv.push((input[idxhv]&0xff).toString());}decoded.hardwareVersion=temphv.join(".");i+=2;}// FIRMWARE VERSIONelseif(channel_id==-1&&channel_type==31){vartempfv=[];varlast_index_fv=i+4;for(varidxfv=i;idxfv<last_index_fv;idxfv++){tempfv.push((input[idxfv]&0xff).toString());}decoded.firmwareVersion=tempfv.join(".");i+=4;}// PEOPLE COUNTERelseif(channel_id==4&&channel_type==-55){decoded.peopleCountAll=input[i];decoded.regionCount=input[i+1];varregion=parseBytesToInt(input,i+2,2,false);for(varidxpc=0;idxpc<decoded.regionCount;idxpc++){vartmp="region"+(idxpc+1);decoded[tmp]=(region>>idxpc)&1;}i+=4;}// PEOPLE IN/OUTelseif(channel_id==5&&channel_type==-52){decoded.peopleIn=parseBytesToInt(input,i,2,false);decoded.peopleOut=parseBytesToInt(input,i+2,2,false);i+=4;}// PEOPLE MAXelseif(channel_id==6&&channel_type==-51){decoded.peopleCountMax=input[i];i+=1;}// REGION COUNTERelseif(channel_id==7&&channel_type==-43){decoded.region1Count=input[i];decoded.region2Count=input[i+1];decoded.region3Count=input[i+2];decoded.region4Count=input[i+3];decoded.region5Count=input[i+4];decoded.region6Count=input[i+5];decoded.region7Count=input[i+6];decoded.region8Count=input[i+7];i+=8;}// REGION COUNTERelseif(channel_id==8&&channel_type==-43){decoded.region9Count=input[i];decoded.region10Count=input[i+1];decoded.region11Count=input[i+2];decoded.region12Count=input[i+3];decoded.region13Count=input[i+4];decoded.region14Count=input[i+5];decoded.region15Count=input[i+6];decoded.region16Count=input[i+7];i+=8;}// A FLOWelseif(channel_id==9&&channel_type==-38){decoded.aToA=parseBytesToInt(input,i,2,false);decoded.aToB=parseBytesToInt(input,i+2,2,false);decoded.aToC=parseBytesToInt(input,i+4,2,false);decoded.aToD=parseBytesToInt(input,i+6,2,false);i+=8;}// B FLOWelseif(channel_id==10&&channel_type==-38){decoded.bToA=parseBytesToInt(input,i,2,false);decoded.bToB=parseBytesToInt(input,i+2,2,false);decoded.bToC=parseBytesToInt(input,i+4,2,false);decoded.bToD=parseBytesToInt(input,i+6,2,false);i+=8;}// C FLOWelseif(channel_id==11&&channel_type==-38){decoded.cToA=parseBytesToInt(input,i,2,false);decoded.cToB=parseBytesToInt(input,i+2,2,false);decoded.cToC=parseBytesToInt(input,i+4,2,false);decoded.cToD=parseBytesToInt(input,i+6,2,false);i+=8;}// D FLOWelseif(channel_id==12&&channel_type==-38){decoded.dToA=parseBytesToInt(input,i,2,false);decoded.dToB=parseBytesToInt(input,i+2,2,false);decoded.dToC=parseBytesToInt(input,i+4,2,false);decoded.dToD=parseBytesToInt(input,i+6,2,false);i+=8;}// TOTAL IN/OUTelseif(channel_id==13&&channel_type==-52){decoded.peopleTotalIn=parseBytesToInt(input,i,2,false);decoded.peopleTotalOut=parseBytesToInt(input,i+2,2,false);i+=4;}// DWELL TIMEelseif(channel_id==14&&channel_type==-28){varregion1=input[i];decoded.region=region1;decoded.dwellTimeAvg=parseBytesToInt(input,i+1,2,false);decoded.dwellTimeMax=parseBytesToInt(input,i+3,2,false);i+=5;}// TIMESTAMPelseif(channel_id==15&&channel_type==-123){decoded.timestamp=parseBytesToInt(input,i,4,false);i+=4;}else{break;}}output.telemetry=decoded;// --- Decoding code --- //returnoutput;}// --- attributes and telemetry objects ---vartelemetry={};varattributes={};// --- attributes and telemetry objects ---// --- Timestamp parsingvardateString=data.time;vartimestamp=-1;if(dateString!=null){timestamp=newDate(dateString).getTime();if(timestamp==-1){varsecondsSeparatorIndex=dateString.lastIndexOf('.')+1;varmillisecondsEndIndex=dateString.lastIndexOf('+');if(millisecondsEndIndex==-1){millisecondsEndIndex=dateString.lastIndexOf('Z');}if(millisecondsEndIndex==-1){millisecondsEndIndex=dateString.lastIndexOf('-');}if(millisecondsEndIndex==-1){if(dateString.length>=secondsSeparatorIndex+3){dateString=dateString.substring(0,secondsSeparatorIndex+3);}}else{dateString=dateString.substring(0,secondsSeparatorIndex+3)+dateString.substring(millisecondsEndIndex,dateString.length);}timestamp=newDate(dateString).getTime();}}// If we cannot parse timestamp - we will use the current timestampif(timestamp==-1){timestamp=Date.now();}// --- Timestamp parsing// You can add some keys manually to attributes or telemetryattributes.deduplicationId=data.deduplicationId;// You can exclude some keys from the resultvarexcludeFromAttributesList=["deviceName","rxInfo","confirmed","data","deduplicationId","time","adr","dr","fCnt"];varexcludeFromTelemetryList=["data","deviceInfo","txInfo","devAddr","adr","time","fPort","region_common_name","region_config_id","deduplicationId"];// Message parsing// To avoid paths in the decoded objects we passing false value to function as "pathInKey" argument.// Warning: pathInKey can cause already found fields to be overwritten with the last value found.vartelemetryData=toFlatMap(data,excludeFromTelemetryList,false);varattributesData=toFlatMap(data,excludeFromAttributesList,false);varuplinkDataList=[];// Passing incoming bytes to decodePayload function, to get custom decodingvarcustomDecoding=decodePayload(base64ToBytes(data.data));// Collecting data to resultif(customDecoding.?telemetry.size()>0){telemetry.putAll(customDecoding.telemetry);}if(customDecoding.?attributes.size()>0){attributes.putAll(customDecoding.attributes);}telemetry.putAll(telemetryData);attributes.putAll(attributesData);varresult={deviceName:deviceName,deviceType:deviceType,// assetName: assetName,// assetType: assetType,// customerName: customerName,// groupName: groupName,attributes:attributes,telemetry:{ts:timestamp,values:telemetry}};returnresult;
varhistoryData={};vardecoded={};decoded.hexString=bytesToHex(input);for(vari=0;i<input.length;){varchannel_id=input[i];varchannel_type=input[i+1];i+=2;// PROTOCOL VERSIONif(channel_id==-1&&channel_type==1){decoded.protocol_version=input[i];i+=1;}// SERIAL NUMBERelseif(channel_id==-1&&channel_type==8){vartemp=[];varlast_index_sn=i+6;for(varidxsn=i;idxsn<last_index_sn;idxsn++){temp.push(bytesToHex([input[idxsn]&0xff]));}decoded.serialNumber=temp.join("");i+=6;}// HARDWARE VERSIONelseif(channel_id==-1&&channel_type==9){vartemphv=[];varlast_index_hv=i+2;for(varidxhv=i;idxhv<last_index_hv;idxhv++){temphv.push((input[idxhv]&0xff).toString());}decoded.hardwareVersion=temphv.join(".");i+=2;}// FIRMWARE VERSIONelseif(channel_id==-1&&channel_type==31){vartempfv=[];varlast_index_fv=i+4;for(varidxfv=i;idxfv<last_index_fv;idxfv++){tempfv.push((input[idxfv]&0xff).toString());}decoded.firmwareVersion=tempfv.join(".");i+=4;}// PEOPLE COUNTERelseif(channel_id==4&&channel_type==-55){decoded.peopleCountAll=input[i];decoded.regionCount=input[i+1];varregion=parseBytesToInt(input,i+2,2,false);for(varidxpc=0;idxpc<decoded.regionCount;idxpc++){vartmp="region"+(idxpc+1);decoded[tmp]=(region>>idxpc)&1;}i+=4;}// PEOPLE IN/OUTelseif(channel_id==5&&channel_type==-52){decoded.peopleIn=parseBytesToInt(input,i,2,false);decoded.peopleOut=parseBytesToInt(input,i+2,2,false);i+=4;}// PEOPLE MAXelseif(channel_id==6&&channel_type==-51){decoded.peopleCountMax=input[i];i+=1;}// REGION COUNTERelseif(channel_id==7&&channel_type==-43){decoded.region1Count=input[i];decoded.region2Count=input[i+1];decoded.region3Count=input[i+2];decoded.region4Count=input[i+3];decoded.region5Count=input[i+4];decoded.region6Count=input[i+5];decoded.region7Count=input[i+6];decoded.region8Count=input[i+7];i+=8;}// REGION COUNTERelseif(channel_id==8&&channel_type==-43){decoded.region9Count=input[i];decoded.region10Count=input[i+1];decoded.region11Count=input[i+2];decoded.region12Count=input[i+3];decoded.region13Count=input[i+4];decoded.region14Count=input[i+5];decoded.region15Count=input[i+6];decoded.region16Count=input[i+7];i+=8;}// A FLOWelseif(channel_id==9&&channel_type==-38){decoded.aToA=parseBytesToInt(input,i,2,false);decoded.aToB=parseBytesToInt(input,i+2,2,false);decoded.aToC=parseBytesToInt(input,i+4,2,false);decoded.aToD=parseBytesToInt(input,i+6,2,false);i+=8;}// B FLOWelseif(channel_id==10&&channel_type==-38){decoded.bToA=parseBytesToInt(input,i,2,false);decoded.bToB=parseBytesToInt(input,i+2,2,false);decoded.bToC=parseBytesToInt(input,i+4,2,false);decoded.bToD=parseBytesToInt(input,i+6,2,false);i+=8;}// C FLOWelseif(channel_id==11&&channel_type==-38){decoded.cToA=parseBytesToInt(input,i,2,false);decoded.cToB=parseBytesToInt(input,i+2,2,false);decoded.cToC=parseBytesToInt(input,i+4,2,false);decoded.cToD=parseBytesToInt(input,i+6,2,false);i+=8;}// D FLOWelseif(channel_id==12&&channel_type==-38){decoded.dToA=parseBytesToInt(input,i,2,false);decoded.dToB=parseBytesToInt(input,i+2,2,false);decoded.dToC=parseBytesToInt(input,i+4,2,false);decoded.dToD=parseBytesToInt(input,i+6,2,false);i+=8;}// TOTAL IN/OUTelseif(channel_id==13&&channel_type==-52){decoded.peopleTotalIn=parseBytesToInt(input,i,2,false);decoded.peopleTotalOut=parseBytesToInt(input,i+2,2,false);i+=4;}// DWELL TIMEelseif(channel_id==14&&channel_type==-28){varregion1=input[i];decoded.region=region1;decoded.dwellTimeAvg=parseBytesToInt(input,i+1,2,false);decoded.dwellTimeMax=parseBytesToInt(input,i+3,2,false);i+=5;}// TIMESTAMPelseif(channel_id==15&&channel_type==-123){decoded.timestamp=parseBytesToInt(input,i,4,false);i+=4;}else{break;}}output.telemetry=decoded;
vardata=decodeToJson(payload);vardeviceName=data.end_device_ids.device_id;vardeviceType=data.end_device_ids.application_ids.application_id;// var groupName = 'IAQ devices';// var customerName = 'Customer A';// use assetName and assetType instead of deviceName and deviceType// to automatically create assets instead of devices.// var assetName = 'Asset A';// var assetType = 'building';// If you want to parse incoming data somehow, you can add your code to this function.// input: bytes// expected output:// {// "attributes": {"attributeKey": "attributeValue"},// "telemetry": {"telemetryKey": "telemetryValue"}// }//// In the example - bytes will be saved as HEX string and also parsed as light level, battery level and PIR sensor value.//functiondecodeFrmPayload(input){varoutput={attributes:{},telemetry:{}};// --- Decoding code --- //output.telemetry.HEX_bytes=bytesToHex(input);varhistoryData={};vardecoded={};decoded.hexString=bytesToHex(input);for(vari=0;i<input.length;){varchannel_id=input[i];varchannel_type=input[i+1];i+=2;// PROTOCOL VERSIONif(channel_id==-1&&channel_type==1){decoded.protocol_version=input[i];i+=1;}// SERIAL NUMBERelseif(channel_id==-1&&channel_type==8){vartemp=[];varlast_index_sn=i+6;for(varidxsn=i;idxsn<last_index_sn;idxsn++){temp.push(bytesToHex([input[idxsn]&0xff]));}decoded.serialNumber=temp.join("");i+=6;}// HARDWARE VERSIONelseif(channel_id==-1&&channel_type==9){vartemphv=[];varlast_index_hv=i+2;for(varidxhv=i;idxhv<last_index_hv;idxhv++){temphv.push((input[idxhv]&0xff).toString());}decoded.hardwareVersion=temphv.join(".");i+=2;}// FIRMWARE VERSIONelseif(channel_id==-1&&channel_type==31){vartempfv=[];varlast_index_fv=i+4;for(varidxfv=i;idxfv<last_index_fv;idxfv++){tempfv.push((input[idxfv]&0xff).toString());}decoded.firmwareVersion=tempfv.join(".");i+=4;}// PEOPLE COUNTERelseif(channel_id==4&&channel_type==-55){decoded.peopleCountAll=input[i];decoded.regionCount=input[i+1];varregion=parseBytesToInt(input,i+2,2,false);for(varidxpc=0;idxpc<decoded.regionCount;idxpc++){vartmp="region"+(idxpc+1);decoded[tmp]=(region>>idxpc)&1;}i+=4;}// PEOPLE IN/OUTelseif(channel_id==5&&channel_type==-52){decoded.peopleIn=parseBytesToInt(input,i,2,false);decoded.peopleOut=parseBytesToInt(input,i+2,2,false);i+=4;}// PEOPLE MAXelseif(channel_id==6&&channel_type==-51){decoded.peopleCountMax=input[i];i+=1;}// REGION COUNTERelseif(channel_id==7&&channel_type==-43){decoded.region1Count=input[i];decoded.region2Count=input[i+1];decoded.region3Count=input[i+2];decoded.region4Count=input[i+3];decoded.region5Count=input[i+4];decoded.region6Count=input[i+5];decoded.region7Count=input[i+6];decoded.region8Count=input[i+7];i+=8;}// REGION COUNTERelseif(channel_id==8&&channel_type==-43){decoded.region9Count=input[i];decoded.region10Count=input[i+1];decoded.region11Count=input[i+2];decoded.region12Count=input[i+3];decoded.region13Count=input[i+4];decoded.region14Count=input[i+5];decoded.region15Count=input[i+6];decoded.region16Count=input[i+7];i+=8;}// A FLOWelseif(channel_id==9&&channel_type==-38){decoded.aToA=parseBytesToInt(input,i,2,false);decoded.aToB=parseBytesToInt(input,i+2,2,false);decoded.aToC=parseBytesToInt(input,i+4,2,false);decoded.aToD=parseBytesToInt(input,i+6,2,false);i+=8;}// B FLOWelseif(channel_id==10&&channel_type==-38){decoded.bToA=parseBytesToInt(input,i,2,false);decoded.bToB=parseBytesToInt(input,i+2,2,false);decoded.bToC=parseBytesToInt(input,i+4,2,false);decoded.bToD=parseBytesToInt(input,i+6,2,false);i+=8;}// C FLOWelseif(channel_id==11&&channel_type==-38){decoded.cToA=parseBytesToInt(input,i,2,false);decoded.cToB=parseBytesToInt(input,i+2,2,false);decoded.cToC=parseBytesToInt(input,i+4,2,false);decoded.cToD=parseBytesToInt(input,i+6,2,false);i+=8;}// D FLOWelseif(channel_id==12&&channel_type==-38){decoded.dToA=parseBytesToInt(input,i,2,false);decoded.dToB=parseBytesToInt(input,i+2,2,false);decoded.dToC=parseBytesToInt(input,i+4,2,false);decoded.dToD=parseBytesToInt(input,i+6,2,false);i+=8;}// TOTAL IN/OUTelseif(channel_id==13&&channel_type==-52){decoded.peopleTotalIn=parseBytesToInt(input,i,2,false);decoded.peopleTotalOut=parseBytesToInt(input,i+2,2,false);i+=4;}// DWELL TIMEelseif(channel_id==14&&channel_type==-28){varregion1=input[i];decoded.region=region1;decoded.dwellTimeAvg=parseBytesToInt(input,i+1,2,false);decoded.dwellTimeMax=parseBytesToInt(input,i+3,2,false);i+=5;}// TIMESTAMPelseif(channel_id==15&&channel_type==-123){decoded.timestamp=parseBytesToInt(input,i,4,false);i+=4;}else{break;}}output.telemetry=decoded;// --- Decoding code --- //returnoutput;}// --- attributes and telemetry objects ---vartelemetry={};varattributes={};// --- attributes and telemetry objects ---// --- Timestamp parsingvardateString=data.uplink_message.received_at;// If data is simulated or device doesn't send his own date string - we will use date from upcoming message, set by network serverif((data.simulated!=null&&data.simulated)||dateString==null){dateString=data.received_at;}vartimestamp=newDate(dateString).getTime();vartimestamp=-1;if(dateString!=null){timestamp=newDate(dateString).getTime();if(timestamp==-1){varsecondsSeparatorIndex=dateString.lastIndexOf('.')+1;varmillisecondsEndIndex=dateString.lastIndexOf('+');if(millisecondsEndIndex==-1){millisecondsEndIndex=dateString.lastIndexOf('Z');}if(millisecondsEndIndex==-1){millisecondsEndIndex=dateString.lastIndexOf('-');}if(millisecondsEndIndex==-1){if(dateString.length>=secondsSeparatorIndex+3){dateString=dateString.substring(0,secondsSeparatorIndex+3);}}else{dateString=dateString.substring(0,secondsSeparatorIndex+3)+dateString.substring(millisecondsEndIndex,dateString.length);}timestamp=newDate(dateString).getTime();}}// If we cannot parse timestamp - we will use the current timestampif(timestamp==-1){timestamp=Date.now();}// --- Timestamp parsing// You can add some keys manually to attributes or telemetryattributes.devEui=data.end_device_ids.dev_eui;attributes.fPort=data.uplink_message.f_port;// We want to save correlation ids as single object, so we are excluding them from attributes parse and add manuallyattributes.correlation_ids=data.correlation_ids;// You can exclude some keys from the resultvarexcludeFromTelemetryList=["uplink_token","gateway_id","settings","f_port","time","timestamp","received_at","network_ids"];varexcludeFromAttributesList=["uplink_token","gateway_id","f_port","time","timestamp","received_at","session_key_id","dev_eui"];// Message parsing// To avoid paths in the decoded objects we passing false value to function as "pathInKey" argument.// Warning: pathInKey can cause already found fields to be overwritten with the last value found, e.g. receive_at from uplink_message will be written receive_at in the root.vartelemetryData=toFlatMap(data.uplink_message,excludeFromTelemetryList,false);varattributesData={};attributesData.putAll(toFlatMap(data.uplink_message.settings,excludeFromAttributesList,false));attributesData.putAll(toFlatMap(data.uplink_message.network_ids,excludeFromAttributesList,false));attributesData.putAll(toFlatMap(data.end_device_ids,excludeFromAttributesList,false));// Passing incoming bytes to decodeFrmPayload function, to get custom decodingvarcustomDecoding={};if(data.uplink_message.get("frm_payload")!=null){customDecoding=decodeFrmPayload(base64ToBytes(data.uplink_message.frm_payload));}// Collecting data to resultif(customDecoding.?telemetry.size()>0){telemetry.putAll(customDecoding.telemetry);}if(customDecoding.?attributes.size()>0){attributes.putAll(customDecoding.attributes);}telemetry.putAll(telemetryData);attributes.putAll(attributesData);varresult={deviceName:deviceName,deviceType:deviceType,// assetName: assetName,// assetType: assetType,// customerName: customerName// groupName: groupName,attributes:attributes,telemetry:{ts:timestamp,values:telemetry}};returnresult;
varhistoryData={};vardecoded={};decoded.hexString=bytesToHex(input);for(vari=0;i<input.length;){varchannel_id=input[i];varchannel_type=input[i+1];i+=2;// PROTOCOL VERSIONif(channel_id==-1&&channel_type==1){decoded.protocol_version=input[i];i+=1;}// SERIAL NUMBERelseif(channel_id==-1&&channel_type==8){vartemp=[];varlast_index_sn=i+6;for(varidxsn=i;idxsn<last_index_sn;idxsn++){temp.push(bytesToHex([input[idxsn]&0xff]));}decoded.serialNumber=temp.join("");i+=6;}// HARDWARE VERSIONelseif(channel_id==-1&&channel_type==9){vartemphv=[];varlast_index_hv=i+2;for(varidxhv=i;idxhv<last_index_hv;idxhv++){temphv.push((input[idxhv]&0xff).toString());}decoded.hardwareVersion=temphv.join(".");i+=2;}// FIRMWARE VERSIONelseif(channel_id==-1&&channel_type==31){vartempfv=[];varlast_index_fv=i+4;for(varidxfv=i;idxfv<last_index_fv;idxfv++){tempfv.push((input[idxfv]&0xff).toString());}decoded.firmwareVersion=tempfv.join(".");i+=4;}// PEOPLE COUNTERelseif(channel_id==4&&channel_type==-55){decoded.peopleCountAll=input[i];decoded.regionCount=input[i+1];varregion=parseBytesToInt(input,i+2,2,false);for(varidxpc=0;idxpc<decoded.regionCount;idxpc++){vartmp="region"+(idxpc+1);decoded[tmp]=(region>>idxpc)&1;}i+=4;}// PEOPLE IN/OUTelseif(channel_id==5&&channel_type==-52){decoded.peopleIn=parseBytesToInt(input,i,2,false);decoded.peopleOut=parseBytesToInt(input,i+2,2,false);i+=4;}// PEOPLE MAXelseif(channel_id==6&&channel_type==-51){decoded.peopleCountMax=input[i];i+=1;}// REGION COUNTERelseif(channel_id==7&&channel_type==-43){decoded.region1Count=input[i];decoded.region2Count=input[i+1];decoded.region3Count=input[i+2];decoded.region4Count=input[i+3];decoded.region5Count=input[i+4];decoded.region6Count=input[i+5];decoded.region7Count=input[i+6];decoded.region8Count=input[i+7];i+=8;}// REGION COUNTERelseif(channel_id==8&&channel_type==-43){decoded.region9Count=input[i];decoded.region10Count=input[i+1];decoded.region11Count=input[i+2];decoded.region12Count=input[i+3];decoded.region13Count=input[i+4];decoded.region14Count=input[i+5];decoded.region15Count=input[i+6];decoded.region16Count=input[i+7];i+=8;}// A FLOWelseif(channel_id==9&&channel_type==-38){decoded.aToA=parseBytesToInt(input,i,2,false);decoded.aToB=parseBytesToInt(input,i+2,2,false);decoded.aToC=parseBytesToInt(input,i+4,2,false);decoded.aToD=parseBytesToInt(input,i+6,2,false);i+=8;}// B FLOWelseif(channel_id==10&&channel_type==-38){decoded.bToA=parseBytesToInt(input,i,2,false);decoded.bToB=parseBytesToInt(input,i+2,2,false);decoded.bToC=parseBytesToInt(input,i+4,2,false);decoded.bToD=parseBytesToInt(input,i+6,2,false);i+=8;}// C FLOWelseif(channel_id==11&&channel_type==-38){decoded.cToA=parseBytesToInt(input,i,2,false);decoded.cToB=parseBytesToInt(input,i+2,2,false);decoded.cToC=parseBytesToInt(input,i+4,2,false);decoded.cToD=parseBytesToInt(input,i+6,2,false);i+=8;}// D FLOWelseif(channel_id==12&&channel_type==-38){decoded.dToA=parseBytesToInt(input,i,2,false);decoded.dToB=parseBytesToInt(input,i+2,2,false);decoded.dToC=parseBytesToInt(input,i+4,2,false);decoded.dToD=parseBytesToInt(input,i+6,2,false);i+=8;}// TOTAL IN/OUTelseif(channel_id==13&&channel_type==-52){decoded.peopleTotalIn=parseBytesToInt(input,i,2,false);decoded.peopleTotalOut=parseBytesToInt(input,i+2,2,false);i+=4;}// DWELL TIMEelseif(channel_id==14&&channel_type==-28){varregion1=input[i];decoded.region=region1;decoded.dwellTimeAvg=parseBytesToInt(input,i+1,2,false);decoded.dwellTimeMax=parseBytesToInt(input,i+3,2,false);i+=5;}// TIMESTAMPelseif(channel_id==15&&channel_type==-123){decoded.timestamp=parseBytesToInt(input,i,4,false);i+=4;}else{break;}}output.telemetry=decoded;
vardata=decodeToJson(payload);vardeviceName=data.end_device_ids.device_id;vardeviceType=data.end_device_ids.application_ids.application_id;// var groupName = 'IAQ devices';// var customerName = 'Customer A';// use assetName and assetType instead of deviceName and deviceType// to automatically create assets instead of devices.// var assetName = 'Asset A';// var assetType = 'building';// If you want to parse incoming data somehow, you can add your code to this function.// input: bytes// expected output:// {// "attributes": {"attributeKey": "attributeValue"},// "telemetry": {"telemetryKey": "telemetryValue"}// }//// In the example - bytes will be saved as HEX string and also parsed as light level, battery level and PIR sensor value.//functiondecodeFrmPayload(input){varoutput={attributes:{},telemetry:{}};// --- Decoding code --- //output.telemetry.HEX_bytes=bytesToHex(input);varhistoryData={};vardecoded={};decoded.hexString=bytesToHex(input);for(vari=0;i<input.length;){varchannel_id=input[i];varchannel_type=input[i+1];i+=2;// PROTOCOL VERSIONif(channel_id==-1&&channel_type==1){decoded.protocol_version=input[i];i+=1;}// SERIAL NUMBERelseif(channel_id==-1&&channel_type==8){vartemp=[];varlast_index_sn=i+6;for(varidxsn=i;idxsn<last_index_sn;idxsn++){temp.push(bytesToHex([input[idxsn]&0xff]));}decoded.serialNumber=temp.join("");i+=6;}// HARDWARE VERSIONelseif(channel_id==-1&&channel_type==9){vartemphv=[];varlast_index_hv=i+2;for(varidxhv=i;idxhv<last_index_hv;idxhv++){temphv.push((input[idxhv]&0xff).toString());}decoded.hardwareVersion=temphv.join(".");i+=2;}// FIRMWARE VERSIONelseif(channel_id==-1&&channel_type==31){vartempfv=[];varlast_index_fv=i+4;for(varidxfv=i;idxfv<last_index_fv;idxfv++){tempfv.push((input[idxfv]&0xff).toString());}decoded.firmwareVersion=tempfv.join(".");i+=4;}// PEOPLE COUNTERelseif(channel_id==4&&channel_type==-55){decoded.peopleCountAll=input[i];decoded.regionCount=input[i+1];varregion=parseBytesToInt(input,i+2,2,false);for(varidxpc=0;idxpc<decoded.regionCount;idxpc++){vartmp="region"+(idxpc+1);decoded[tmp]=(region>>idxpc)&1;}i+=4;}// PEOPLE IN/OUTelseif(channel_id==5&&channel_type==-52){decoded.peopleIn=parseBytesToInt(input,i,2,false);decoded.peopleOut=parseBytesToInt(input,i+2,2,false);i+=4;}// PEOPLE MAXelseif(channel_id==6&&channel_type==-51){decoded.peopleCountMax=input[i];i+=1;}// REGION COUNTERelseif(channel_id==7&&channel_type==-43){decoded.region1Count=input[i];decoded.region2Count=input[i+1];decoded.region3Count=input[i+2];decoded.region4Count=input[i+3];decoded.region5Count=input[i+4];decoded.region6Count=input[i+5];decoded.region7Count=input[i+6];decoded.region8Count=input[i+7];i+=8;}// REGION COUNTERelseif(channel_id==8&&channel_type==-43){decoded.region9Count=input[i];decoded.region10Count=input[i+1];decoded.region11Count=input[i+2];decoded.region12Count=input[i+3];decoded.region13Count=input[i+4];decoded.region14Count=input[i+5];decoded.region15Count=input[i+6];decoded.region16Count=input[i+7];i+=8;}// A FLOWelseif(channel_id==9&&channel_type==-38){decoded.aToA=parseBytesToInt(input,i,2,false);decoded.aToB=parseBytesToInt(input,i+2,2,false);decoded.aToC=parseBytesToInt(input,i+4,2,false);decoded.aToD=parseBytesToInt(input,i+6,2,false);i+=8;}// B FLOWelseif(channel_id==10&&channel_type==-38){decoded.bToA=parseBytesToInt(input,i,2,false);decoded.bToB=parseBytesToInt(input,i+2,2,false);decoded.bToC=parseBytesToInt(input,i+4,2,false);decoded.bToD=parseBytesToInt(input,i+6,2,false);i+=8;}// C FLOWelseif(channel_id==11&&channel_type==-38){decoded.cToA=parseBytesToInt(input,i,2,false);decoded.cToB=parseBytesToInt(input,i+2,2,false);decoded.cToC=parseBytesToInt(input,i+4,2,false);decoded.cToD=parseBytesToInt(input,i+6,2,false);i+=8;}// D FLOWelseif(channel_id==12&&channel_type==-38){decoded.dToA=parseBytesToInt(input,i,2,false);decoded.dToB=parseBytesToInt(input,i+2,2,false);decoded.dToC=parseBytesToInt(input,i+4,2,false);decoded.dToD=parseBytesToInt(input,i+6,2,false);i+=8;}// TOTAL IN/OUTelseif(channel_id==13&&channel_type==-52){decoded.peopleTotalIn=parseBytesToInt(input,i,2,false);decoded.peopleTotalOut=parseBytesToInt(input,i+2,2,false);i+=4;}// DWELL TIMEelseif(channel_id==14&&channel_type==-28){varregion1=input[i];decoded.region=region1;decoded.dwellTimeAvg=parseBytesToInt(input,i+1,2,false);decoded.dwellTimeMax=parseBytesToInt(input,i+3,2,false);i+=5;}// TIMESTAMPelseif(channel_id==15&&channel_type==-123){decoded.timestamp=parseBytesToInt(input,i,4,false);i+=4;}else{break;}}output.telemetry=decoded;// --- Decoding code --- //returnoutput;}// --- attributes and telemetry objects ---vartelemetry={};varattributes={};// --- attributes and telemetry objects ---// --- Timestamp parsingvardateString=data.uplink_message.received_at;// If data is simulated or device doesn't send his own date string - we will use date from upcoming message, set by network serverif((data.simulated!=null&&data.simulated)||dateString==null){dateString=data.received_at;}vartimestamp=-1;if(dateString!=null){timestamp=newDate(dateString).getTime();if(timestamp==-1){varsecondsSeparatorIndex=dateString.lastIndexOf('.')+1;varmillisecondsEndIndex=dateString.lastIndexOf('+');if(millisecondsEndIndex==-1){millisecondsEndIndex=dateString.lastIndexOf('Z');}if(millisecondsEndIndex==-1){millisecondsEndIndex=dateString.lastIndexOf('-');}if(millisecondsEndIndex==-1){if(dateString.length>=secondsSeparatorIndex+3){dateString=dateString.substring(0,secondsSeparatorIndex+3);}}else{dateString=dateString.substring(0,secondsSeparatorIndex+3)+dateString.substring(millisecondsEndIndex,dateString.length);}timestamp=newDate(dateString).getTime();}}// If we cannot parse timestamp - we will use the current timestampif(timestamp==-1){timestamp=Date.now();}// --- Timestamp parsing// You can add some keys manually to attributes or telemetryattributes.devEui=data.end_device_ids.dev_eui;attributes.fPort=data.uplink_message.f_port;// We want to save correlation ids as single object, so we are excluding them from attributes parse and add manuallyattributes.correlation_ids=data.correlation_ids;// You can exclude some keys from the resultvarexcludeFromTelemetryList=["uplink_token","gateway_id","settings","f_port","time","timestamp","received_at","network_ids"];varexcludeFromAttributesList=["uplink_token","gateway_id","f_port","time","timestamp","received_at","session_key_id","dev_eui"];// Message parsing// To avoid paths in the decoded objects we passing false value to function as "pathInKey" argument.// Warning: pathInKey can cause already found fields to be overwritten with the last value found, e.g. receive_at from uplink_message will be written receive_at in the root.vartelemetryData=toFlatMap(data.uplink_message,excludeFromTelemetryList,false);varattributesData={};attributesData.putAll(toFlatMap(data.uplink_message.settings,excludeFromAttributesList,false));attributesData.putAll(toFlatMap(data.uplink_message.network_ids,excludeFromAttributesList,false));attributesData.putAll(toFlatMap(data.end_device_ids,excludeFromAttributesList,false));// Passing incoming bytes to decodeFrmPayload function, to get custom decodingvarcustomDecoding={};if(data.uplink_message.get("frm_payload")!=null){customDecoding=decodeFrmPayload(base64ToBytes(data.uplink_message.frm_payload));}// Collecting data to resultif(customDecoding.?telemetry.size()>0){telemetry.putAll(customDecoding.telemetry);}if(customDecoding.?attributes.size()>0){attributes.putAll(customDecoding.attributes);}telemetry.putAll(telemetryData);attributes.putAll(attributesData);varresult={deviceName:deviceName,deviceType:deviceType,// assetName: assetName,// assetType: assetType,// customerName: customerName,// groupName: groupName,attributes:attributes,telemetry:{ts:timestamp,values:telemetry}};returnresult;
varhistoryData={};vardecoded={};decoded.hexString=bytesToHex(input);for(vari=0;i<input.length;){varchannel_id=input[i];varchannel_type=input[i+1];i+=2;// PROTOCOL VERSIONif(channel_id==-1&&channel_type==1){decoded.protocol_version=input[i];i+=1;}// SERIAL NUMBERelseif(channel_id==-1&&channel_type==8){vartemp=[];varlast_index_sn=i+6;for(varidxsn=i;idxsn<last_index_sn;idxsn++){temp.push(bytesToHex([input[idxsn]&0xff]));}decoded.serialNumber=temp.join("");i+=6;}// HARDWARE VERSIONelseif(channel_id==-1&&channel_type==9){vartemphv=[];varlast_index_hv=i+2;for(varidxhv=i;idxhv<last_index_hv;idxhv++){temphv.push((input[idxhv]&0xff).toString());}decoded.hardwareVersion=temphv.join(".");i+=2;}// FIRMWARE VERSIONelseif(channel_id==-1&&channel_type==31){vartempfv=[];varlast_index_fv=i+4;for(varidxfv=i;idxfv<last_index_fv;idxfv++){tempfv.push((input[idxfv]&0xff).toString());}decoded.firmwareVersion=tempfv.join(".");i+=4;}// PEOPLE COUNTERelseif(channel_id==4&&channel_type==-55){decoded.peopleCountAll=input[i];decoded.regionCount=input[i+1];varregion=parseBytesToInt(input,i+2,2,false);for(varidxpc=0;idxpc<decoded.regionCount;idxpc++){vartmp="region"+(idxpc+1);decoded[tmp]=(region>>idxpc)&1;}i+=4;}// PEOPLE IN/OUTelseif(channel_id==5&&channel_type==-52){decoded.peopleIn=parseBytesToInt(input,i,2,false);decoded.peopleOut=parseBytesToInt(input,i+2,2,false);i+=4;}// PEOPLE MAXelseif(channel_id==6&&channel_type==-51){decoded.peopleCountMax=input[i];i+=1;}// REGION COUNTERelseif(channel_id==7&&channel_type==-43){decoded.region1Count=input[i];decoded.region2Count=input[i+1];decoded.region3Count=input[i+2];decoded.region4Count=input[i+3];decoded.region5Count=input[i+4];decoded.region6Count=input[i+5];decoded.region7Count=input[i+6];decoded.region8Count=input[i+7];i+=8;}// REGION COUNTERelseif(channel_id==8&&channel_type==-43){decoded.region9Count=input[i];decoded.region10Count=input[i+1];decoded.region11Count=input[i+2];decoded.region12Count=input[i+3];decoded.region13Count=input[i+4];decoded.region14Count=input[i+5];decoded.region15Count=input[i+6];decoded.region16Count=input[i+7];i+=8;}// A FLOWelseif(channel_id==9&&channel_type==-38){decoded.aToA=parseBytesToInt(input,i,2,false);decoded.aToB=parseBytesToInt(input,i+2,2,false);decoded.aToC=parseBytesToInt(input,i+4,2,false);decoded.aToD=parseBytesToInt(input,i+6,2,false);i+=8;}// B FLOWelseif(channel_id==10&&channel_type==-38){decoded.bToA=parseBytesToInt(input,i,2,false);decoded.bToB=parseBytesToInt(input,i+2,2,false);decoded.bToC=parseBytesToInt(input,i+4,2,false);decoded.bToD=parseBytesToInt(input,i+6,2,false);i+=8;}// C FLOWelseif(channel_id==11&&channel_type==-38){decoded.cToA=parseBytesToInt(input,i,2,false);decoded.cToB=parseBytesToInt(input,i+2,2,false);decoded.cToC=parseBytesToInt(input,i+4,2,false);decoded.cToD=parseBytesToInt(input,i+6,2,false);i+=8;}// D FLOWelseif(channel_id==12&&channel_type==-38){decoded.dToA=parseBytesToInt(input,i,2,false);decoded.dToB=parseBytesToInt(input,i+2,2,false);decoded.dToC=parseBytesToInt(input,i+4,2,false);decoded.dToD=parseBytesToInt(input,i+6,2,false);i+=8;}// TOTAL IN/OUTelseif(channel_id==13&&channel_type==-52){decoded.peopleTotalIn=parseBytesToInt(input,i,2,false);decoded.peopleTotalOut=parseBytesToInt(input,i+2,2,false);i+=4;}// DWELL TIMEelseif(channel_id==14&&channel_type==-28){varregion1=input[i];decoded.region=region1;decoded.dwellTimeAvg=parseBytesToInt(input,i+1,2,false);decoded.dwellTimeMax=parseBytesToInt(input,i+3,2,false);i+=5;}// TIMESTAMPelseif(channel_id==15&&channel_type==-123){decoded.timestamp=parseBytesToInt(input,i,4,false);i+=4;}else{break;}}output.telemetry=decoded;
vardata=decodeToJson(payload);vardeviceName=data.EUI;vardeviceType="LoraDevices";// groupName = 'IAQ devices';// var customerName = 'Customer A';// use assetName and assetType instead of deviceName and deviceType// to automatically create assets instead of devices.// var assetName = 'Asset A';// var assetType = 'building';vargatewayDeviceType="LoraGateway";// If you want to parse incoming data somehow, you can add your code to this function.// input: bytes// expected output:// {// "attributes": {"attributeKey": "attributeValue"},// "telemetry": {"telemetryKey": "telemetryValue"}// }//// In the example - bytes will be saved as HEX string and also parsed as light level, battery level and PIR sensor value.//functiondecodePayload(input){varoutput={attributes:{},telemetry:{}};// --- Decoding code --- //output.telemetry.HEX_bytes=bytesToHex(input);varhistoryData={};vardecoded={};decoded.hexString=bytesToHex(input);for(vari=0;i<input.length;){varchannel_id=input[i];varchannel_type=input[i+1];i+=2;// PROTOCOL VERSIONif(channel_id==-1&&channel_type==1){decoded.protocol_version=input[i];i+=1;}// SERIAL NUMBERelseif(channel_id==-1&&channel_type==8){vartemp=[];varlast_index_sn=i+6;for(varidxsn=i;idxsn<last_index_sn;idxsn++){temp.push(bytesToHex([input[idxsn]&0xff]));}decoded.serialNumber=temp.join("");i+=6;}// HARDWARE VERSIONelseif(channel_id==-1&&channel_type==9){vartemphv=[];varlast_index_hv=i+2;for(varidxhv=i;idxhv<last_index_hv;idxhv++){temphv.push((input[idxhv]&0xff).toString());}decoded.hardwareVersion=temphv.join(".");i+=2;}// FIRMWARE VERSIONelseif(channel_id==-1&&channel_type==31){vartempfv=[];varlast_index_fv=i+4;for(varidxfv=i;idxfv<last_index_fv;idxfv++){tempfv.push((input[idxfv]&0xff).toString());}decoded.firmwareVersion=tempfv.join(".");i+=4;}// PEOPLE COUNTERelseif(channel_id==4&&channel_type==-55){decoded.peopleCountAll=input[i];decoded.regionCount=input[i+1];varregion=parseBytesToInt(input,i+2,2,false);for(varidxpc=0;idxpc<decoded.regionCount;idxpc++){vartmp="region"+(idxpc+1);decoded[tmp]=(region>>idxpc)&1;}i+=4;}// PEOPLE IN/OUTelseif(channel_id==5&&channel_type==-52){decoded.peopleIn=parseBytesToInt(input,i,2,false);decoded.peopleOut=parseBytesToInt(input,i+2,2,false);i+=4;}// PEOPLE MAXelseif(channel_id==6&&channel_type==-51){decoded.peopleCountMax=input[i];i+=1;}// REGION COUNTERelseif(channel_id==7&&channel_type==-43){decoded.region1Count=input[i];decoded.region2Count=input[i+1];decoded.region3Count=input[i+2];decoded.region4Count=input[i+3];decoded.region5Count=input[i+4];decoded.region6Count=input[i+5];decoded.region7Count=input[i+6];decoded.region8Count=input[i+7];i+=8;}// REGION COUNTERelseif(channel_id==8&&channel_type==-43){decoded.region9Count=input[i];decoded.region10Count=input[i+1];decoded.region11Count=input[i+2];decoded.region12Count=input[i+3];decoded.region13Count=input[i+4];decoded.region14Count=input[i+5];decoded.region15Count=input[i+6];decoded.region16Count=input[i+7];i+=8;}// A FLOWelseif(channel_id==9&&channel_type==-38){decoded.aToA=parseBytesToInt(input,i,2,false);decoded.aToB=parseBytesToInt(input,i+2,2,false);decoded.aToC=parseBytesToInt(input,i+4,2,false);decoded.aToD=parseBytesToInt(input,i+6,2,false);i+=8;}// B FLOWelseif(channel_id==10&&channel_type==-38){decoded.bToA=parseBytesToInt(input,i,2,false);decoded.bToB=parseBytesToInt(input,i+2,2,false);decoded.bToC=parseBytesToInt(input,i+4,2,false);decoded.bToD=parseBytesToInt(input,i+6,2,false);i+=8;}// C FLOWelseif(channel_id==11&&channel_type==-38){decoded.cToA=parseBytesToInt(input,i,2,false);decoded.cToB=parseBytesToInt(input,i+2,2,false);decoded.cToC=parseBytesToInt(input,i+4,2,false);decoded.cToD=parseBytesToInt(input,i+6,2,false);i+=8;}// D FLOWelseif(channel_id==12&&channel_type==-38){decoded.dToA=parseBytesToInt(input,i,2,false);decoded.dToB=parseBytesToInt(input,i+2,2,false);decoded.dToC=parseBytesToInt(input,i+4,2,false);decoded.dToD=parseBytesToInt(input,i+6,2,false);i+=8;}// TOTAL IN/OUTelseif(channel_id==13&&channel_type==-52){decoded.peopleTotalIn=parseBytesToInt(input,i,2,false);decoded.peopleTotalOut=parseBytesToInt(input,i+2,2,false);i+=4;}// DWELL TIMEelseif(channel_id==14&&channel_type==-28){varregion1=input[i];decoded.region=region1;decoded.dwellTimeAvg=parseBytesToInt(input,i+1,2,false);decoded.dwellTimeMax=parseBytesToInt(input,i+3,2,false);i+=5;}// TIMESTAMPelseif(channel_id==15&&channel_type==-123){decoded.timestamp=parseBytesToInt(input,i,4,false);i+=4;}else{break;}}output.telemetry=decoded;// --- Decoding code --- //returnoutput;}// --- attributes and telemetry objects ---vartelemetry={};varattributes={};// --- attributes and telemetry objects ---// --- Timestamp parsingvartimestamp=data.ts;// If we cannot parse timestamp - we will use the current timestampif(timestamp==-1){timestamp=Date.now();}// --- Timestamp parsing// You can add some keys manually to attributes or telemetryattributes.fPort=data.port;attributes.dataRange=data.dr;// You can exclude some keys from the resultvarexcludeFromAttributesList=["data","gws","EUI","ts","cmd","port","seqno","fcnt","toa","dr","ack","bat","snr","rssi"];varexcludeFromTelemetryList=["gws","EUI","ts","freq","port","data","cmd","dr","offline"];// Message parsing// To avoid paths in the decoded objects we passing false value to function as "pathInKey" argument.// Warning: pathInKey can cause already found fields to be overwritten with the last value found.vartelemetryData=toFlatMap(data,excludeFromTelemetryList,false);varattributesData=toFlatMap(data,excludeFromAttributesList,false);varuplinkDataList=[];// Passing incoming bytes to decodePayload function, to get custom decodingvarcustomDecoding=decodePayload(hexToBytes(data.data));// Collecting data to resultif(customDecoding.?telemetry.size()>0){telemetry.putAll(customDecoding.telemetry);}if(customDecoding.?attributes.size()>0){attributes.putAll(customDecoding.attributes);}telemetry.putAll(telemetryData);attributes.putAll(attributesData);vardeviceInfo={deviceName:deviceName,deviceType:deviceType,// assetName: assetName,// assetType: assetType,// customerName: customerName,// groupName: groupName,attributes:attributes,telemetry:{ts:timestamp,values:telemetry}};uplinkDataList.add(deviceInfo);if(data.cmd=="gw"){foreach(gatewayInfo:data.gws){vargatewayInfoMsg={deviceName:gatewayInfo.gweui,deviceType:gatewayDeviceType,attributes:{},telemetry:{"ts":gatewayInfo.ts,"values":toFlatMap(gatewayInfo,["ts","time","gweui"],false)}};uplinkDataList.add(gatewayInfoMsg);}}returnuplinkDataList;