Sensor
function decodeUplink (input) { const bytes = input['bytes'] const fport = parseInt(input['fPort']) const bytesString = bytes2HexString(bytes) const originMessage = bytesString.toLocaleUpperCase() const decoded = { valid: true, err: 0, payload: bytesString, messages: [] } if (fport === 199 || fport === 192) { decoded.messages.push({fport: fport, payload: bytesString}) return { data: decoded } } if (fport !== 5) { decoded.valid = false return { data: decoded } } let measurement = messageAnalyzed(originMessage) if (measurement.length === 0) { decoded.valid = false return { data: decoded } } for (let message of measurement) { if (message.length === 0) { continue } let elements = [] for (let element of message) { if (element.errorCode) { decoded.err = element.errorCode decoded.errMessage = element.error } else { elements.push(element) } } if (elements.length > 0) { decoded.messages.push(elements) } } // decoded.messages = measurement return { data: decoded } } function messageAnalyzed (messageValue) { try { let frames = unpack(messageValue) let measurementResultArray = [] for (let i = 0; i < frames.length; i++) { let item = frames[i] let dataId = item.dataId let dataValue = item.dataValue let measurementArray = deserialize(dataId, dataValue) measurementResultArray.push(measurementArray) } return measurementResultArray } catch (e) { return e.toString() } } function unpack (messageValue) { let frameArray = [] for (let i = 0; i < messageValue.length; i++) { let remainMessage = messageValue let dataId = remainMessage.substring(0, 2).toUpperCase() let dataValue let dataObj = {} let packageLen switch (dataId) { case '01': packageLen = 94 if (remainMessage.length < packageLen) { return frameArray } dataValue = remainMessage.substring(2, packageLen) messageValue = remainMessage.substring(packageLen) dataObj = { 'dataId': dataId, 'dataValue': dataValue } break case '02': packageLen = 32 if (remainMessage.length < packageLen) { return frameArray } dataValue = remainMessage.substring(2, packageLen) messageValue = remainMessage.substring(packageLen) dataObj = { 'dataId': dataId, 'dataValue': dataValue } break case '03': packageLen = 64 if (remainMessage.length < packageLen) { return frameArray } dataValue = remainMessage.substring(2, packageLen) messageValue = remainMessage.substring(packageLen) dataObj = { 'dataId': dataId, 'dataValue': dataValue } break case '04': packageLen = 20 if (remainMessage.length < packageLen) { return frameArray } dataValue = remainMessage.substring(2, packageLen) messageValue = remainMessage.substring(packageLen) dataObj = { 'dataId': dataId, 'dataValue': dataValue } break case '05': packageLen = 10 if (remainMessage.length < packageLen) { return frameArray } dataValue = remainMessage.substring(2, packageLen) messageValue = remainMessage.substring(packageLen) dataObj = { 'dataId': dataId, 'dataValue': dataValue } break case '06': packageLen = 44 if (remainMessage.length < packageLen) { return frameArray } dataValue = remainMessage.substring(2, packageLen) messageValue = remainMessage.substring(packageLen) dataObj = { 'dataId': dataId, 'dataValue': dataValue } break case '07': packageLen = 84 if (remainMessage.length < packageLen) { return frameArray } dataValue = remainMessage.substring(2, packageLen) messageValue = remainMessage.substring(packageLen) dataObj = { 'dataId': dataId, 'dataValue': dataValue } break case '08': packageLen = 70 if (remainMessage.length < packageLen) { return frameArray } dataValue = remainMessage.substring(2, packageLen) messageValue = remainMessage.substring(packageLen) dataObj = { 'dataId': dataId, 'dataValue': dataValue } break case '09': packageLen = 36 if (remainMessage.length < packageLen) { return frameArray } dataValue = remainMessage.substring(2, packageLen) messageValue = remainMessage.substring(packageLen) dataObj = { 'dataId': dataId, 'dataValue': dataValue } break case '0A': packageLen = 76 if (remainMessage.length < packageLen) { return frameArray } dataValue = remainMessage.substring(2, packageLen) messageValue = remainMessage.substring(packageLen) dataObj = { 'dataId': dataId, 'dataValue': dataValue } break case '0B': packageLen = 62 if (remainMessage.length < packageLen) { return frameArray } dataValue = remainMessage.substring(2, packageLen) messageValue = remainMessage.substring(packageLen) dataObj = { 'dataId': dataId, 'dataValue': dataValue } break case '0C': packageLen = 2 if (remainMessage.length < packageLen) { return frameArray } break case '0D': packageLen = 10 if (remainMessage.length < packageLen) { return frameArray } dataValue = remainMessage.substring(2, packageLen) messageValue = remainMessage.substring(packageLen) dataObj = { 'dataId': dataId, 'dataValue': dataValue } break case '0E': packageLen = getInt(remainMessage.substring(8, 10)) * 2 + 10 if (remainMessage.length < packageLen) { return frameArray } dataValue = remainMessage.substring(2, 8) + remainMessage.substring(10, packageLen) messageValue = remainMessage.substring(packageLen) dataObj = { 'dataId': dataId, 'dataValue': dataValue } break case '0F': packageLen = 34 if (remainMessage.length < packageLen) { return frameArray } dataValue = remainMessage.substring(2, packageLen) messageValue = remainMessage.substring(packageLen) dataObj = { 'dataId': dataId, 'dataValue': dataValue } break case '10': packageLen = 26 if (remainMessage.length < packageLen) { return frameArray } dataValue = remainMessage.substring(2, packageLen) messageValue = remainMessage.substring(packageLen) dataObj = { 'dataId': dataId, 'dataValue': dataValue } break case '11': packageLen = 28 if (remainMessage.length < packageLen) { return frameArray } dataValue = remainMessage.substring(2, packageLen) messageValue = remainMessage.substring(packageLen) dataObj = { 'dataId': dataId, 'dataValue': dataValue } break default: return frameArray } if (dataValue.length < 2) { break } frameArray.push(dataObj) } return frameArray } function deserialize (dataId, dataValue) { let measurementArray = [] let eventList = [] let measurement = {} let collectTime = 0 let groupId = 0 let shardFlag = {} let payload = '' let result = [] let dataArr = [] switch (dataId) { case '01': measurementArray = getUpShortInfo(dataValue) measurementArray.push(...getMotionSetting(dataValue.substring(30, 40))) measurementArray.push(...getStaticSetting(dataValue.substring(40, 46))) measurementArray.push(...getShockSetting(dataValue.substring(46, 52))) measurementArray.push(...getTempSetting(dataValue.substring(52, 72))) measurementArray.push(...getLightSetting(dataValue.substring(72, 92))) break case '02': measurementArray = getUpShortInfo(dataValue) break case '03': measurementArray.push(...getMotionSetting(dataValue.substring(0, 10))) measurementArray.push(...getStaticSetting(dataValue.substring(10, 16))) measurementArray.push(...getShockSetting(dataValue.substring(16, 22))) measurementArray.push(...getTempSetting(dataValue.substring(22, 42))) measurementArray.push(...getLightSetting(dataValue.substring(42, 62))) break case '04': let interval = 0 let workMode = getInt(dataValue.substring(0, 2)) let heartbeatInterval = getMinsByMin(dataValue.substring(4, 8)) let periodicInterval = getMinsByMin(dataValue.substring(8, 12)) let eventInterval = getMinsByMin(dataValue.substring(12, 16)) switch (workMode) { case 0: interval = heartbeatInterval break case 1: interval = periodicInterval break case 2: interval = eventInterval break } measurementArray = [ {measurementId: '3940', type: 'Work Mode', measurementValue: workMode}, {measurementId: '3942', type: 'Heartbeat Interval', measurementValue: heartbeatInterval}, {measurementId: '3943', type: 'Periodic Interval', measurementValue: periodicInterval}, {measurementId: '3944', type: 'Event Interval', measurementValue: eventInterval}, {measurementId: '3941', type: 'SOS Mode', measurementValue: getSOSMode(dataValue.substring(16, 18))}, {measurementId: '3900', type: 'Uplink Interval', measurementValue: interval} ] break; case '05': measurementArray = [ {measurementId: '3000', type: 'Battery', measurementValue: getBattery(dataValue.substring(0, 2))}, {measurementId: '3940', type: 'Work Mode', measurementValue: getWorkingMode(dataValue.substring(2, 4))}, {measurementId: '3965', type: 'Positioning Strategy', measurementValue: getPositioningStrategy(dataValue.substring(4, 6))}, {measurementId: '3941', type: 'SOS Mode', measurementValue: getSOSMode(dataValue.substring(6, 8))} ] break case '06': collectTime = getUTCTimestamp(dataValue.substring(8, 16)) measurementArray = [ {measurementId: '4200', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), type: 'Event Status', measurementValue: getEventStatus(dataValue.substring(0, 6))}, {measurementId: '4197', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), type: 'Longitude', measurementValue: parseFloat(getSensorValue(dataValue.substring(16, 24), 1000000))}, {measurementId: '4198', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), type: 'Latitude', measurementValue: parseFloat(getSensorValue(dataValue.substring(24, 32), 1000000))}, {measurementId: '4097', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), type: 'Air Temperature', measurementValue: getSensorValue(dataValue.substring(32, 36), 10)}, {measurementId: '4199', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), type: 'Light', measurementValue: getSensorValue(dataValue.substring(36, 40))}, {measurementId: '3000', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), type: 'Battery', measurementValue: getBattery(dataValue.substring(40, 42))} ] break case '07': eventList = getEventStatus(dataValue.substring(0, 6)) collectTime = getUTCTimestamp(dataValue.substring(8, 16)) measurementArray = [ {measurementId: '4200', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), type: 'Event Status', measurementValue: getEventStatus(dataValue.substring(0, 6))}, {measurementId: '5001', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), type: 'Wi-Fi Scan', measurementValue: getMacAndRssiObj(dataValue.substring(16, 72))}, {measurementId: '4097', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), type: 'Air Temperature', measurementValue: getSensorValue(dataValue.substring(72, 76), 10)}, {measurementId: '4199', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), type: 'Light', measurementValue: getSensorValue(dataValue.substring(76, 80))}, {measurementId: '3000', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), type: 'Battery', measurementValue: getBattery(dataValue.substring(80, 82))} ] break case '08': collectTime = getUTCTimestamp(dataValue.substring(8, 16)) measurementArray = [ {measurementId: '4200', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), type: 'Event Status', measurementValue: getEventStatus(dataValue.substring(0, 6))}, {measurementId: '5002', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), type: 'BLE Scan', measurementValue: getMacAndRssiObj(dataValue.substring(16, 58))}, {measurementId: '4097', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), type: 'Air Temperature', measurementValue: getSensorValue(dataValue.substring(58, 62), 10)}, {measurementId: '4199', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), type: 'Light', measurementValue: getSensorValue(dataValue.substring(62, 66))}, {measurementId: '3000', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), type: 'Battery', measurementValue: getBattery(dataValue.substring(66, 68))} ] break case '09': collectTime = getUTCTimestamp(dataValue.substring(8, 16)) measurementArray = [ {measurementId: '4200', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), type: 'Event Status', measurementValue: getEventStatus(dataValue.substring(0, 6))}, {measurementId: '4197', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), type: 'Longitude', measurementValue: parseFloat(getSensorValue(dataValue.substring(16, 24), 1000000))}, {measurementId: '4198', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), type: 'Latitude', measurementValue: parseFloat(getSensorValue(dataValue.substring(24, 32), 1000000))}, {measurementId: '3000', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), type: 'Battery', measurementValue: getBattery(dataValue.substring(32, 34))} ] break case '0A': collectTime = getUTCTimestamp(dataValue.substring(8, 16)) measurementArray = [ {measurementId: '4200', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), type: 'Event Status', measurementValue: getEventStatus(dataValue.substring(0, 6))}, {measurementId: '5001', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), type: 'Wi-Fi Scan', measurementValue: getMacAndRssiObj(dataValue.substring(16, 72))}, {measurementId: '3000', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), type: 'Battery', measurementValue: getBattery(dataValue.substring(72, 74))} ] break case '0B': collectTime = getUTCTimestamp(dataValue.substring(8, 16)) measurementArray = [ {measurementId: '4200', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), type: 'Event Status', measurementValue: getEventStatus(dataValue.substring(0, 6))}, {measurementId: '5002', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), type: 'BLE Scan', measurementValue: getMacAndRssiObj(dataValue.substring(16, 58))}, {measurementId: '3000', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), type: 'Battery', measurementValue: getBattery(dataValue.substring(58, 60))}, ] break case '0D': let errorCode = getInt(dataValue) let error = '' switch (errorCode) { case 1: error = 'FAILED TO OBTAIN THE UTC TIMESTAMP' break case 2: error = 'ALMANAC TOO OLD' break case 3: error = 'DOPPLER ERROR' break } measurementArray.push({errorCode, error}) break case '0E': shardFlag = getShardFlag(dataValue.substring(0, 2)) groupId = getInt(dataValue.substring(2, 6)) payload = dataValue.substring(6) measurement = { measurementId: '6152', groupId: groupId, index: shardFlag.index, count: shardFlag.count, type: 'gnss-ng payload', measurementValue: payload } measurementArray.push(measurement) break case '0F': collectTime = getUTCTimestamp(dataValue.substring(8, 16)) shardFlag = getShardFlag(dataValue.substring(26, 28)) groupId = getInt(dataValue.substring(28, 32)) measurementArray.push({ measurementId: '4200', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), groupId: groupId, index: shardFlag.index, count: shardFlag.count, type: 'Event Status', measurementValue: getEventStatus(dataValue.substring(0, 6)) }) measurementArray.push({ measurementId: '4097', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), groupId: groupId, index: shardFlag.index, count: shardFlag.count, type: 'Air Temperature', measurementValue: '' + getSensorValue(dataValue.substring(16, 20), 10) }) measurementArray.push({ measurementId: '4199', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), groupId: groupId, index: shardFlag.index, count: shardFlag.count, type: 'Light', measurementValue: '' + getSensorValue(dataValue.substring(20, 24)) }) measurementArray.push({ measurementId: '3000', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), groupId: groupId, index: shardFlag.index, count: shardFlag.count, type: 'Battery', measurementValue: '' + getBattery(dataValue.substring(24, 26)) }) break case '10': collectTime = getUTCTimestamp(dataValue.substring(8, 16)) shardFlag = getShardFlag(dataValue.substring(18, 20)) groupId = getInt(dataValue.substring(20, 24)) measurementArray.push({ measurementId: '4200', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), groupId: groupId, index: shardFlag.index, count: shardFlag.count, type: 'Event Status', measurementValue: getEventStatus(dataValue.substring(0, 6)) }) measurementArray.push({ measurementId: '3000', timestamp: collectTime, motionId: getMotionId(dataValue.substring(6, 8)), groupId: groupId, index: shardFlag.index, count: shardFlag.count, type: 'Battery', measurementValue: '' + getBattery(dataValue.substring(16, 18)) }) break case '11': collectTime = getUTCTimestamp(dataValue.substring(8, 16)) measurementArray.push({ measurementId: '3576', timestamp: collectTime, type: 'Positing Status', measurementValue: '' + getPositingStatus(dataValue.substring(0, 2)) }) measurementArray.push({ timestamp: collectTime, measurementId: '4200', type: 'Event Status', measurementValue: getEventStatus(dataValue.substring(2, 8)) }) if (!isNaN(parseFloat(getSensorValue(dataValue.substring(16, 20), 10)))) { measurementArray.push({ timestamp: collectTime, measurementId: '4097', type: 'Air Temperature', measurementValue: '' + getSensorValue(dataValue.substring(16, 20), 10) }) } if (!isNaN(parseFloat(getSensorValue(dataValue.substring(20, 24))))) { measurementArray.push({ timestamp: collectTime, measurementId: '4199', type: 'Light', measurementValue: '' + getSensorValue(dataValue.substring(20, 24)) }) } measurementArray.push({ timestamp: collectTime, measurementId: '3000', type: 'Battery', measurementValue: '' + getBattery(dataValue.substring(24, 26)) }) break } return measurementArray } function getMotionId (str) { return getInt(str) } function getPositingStatus (str) { return getInt(str) } function getUpShortInfo (messageValue) { return [ { measurementId: '3000', type: 'Battery', measurementValue: getBattery(messageValue.substring(0, 2)) }, { measurementId: '3502', type: 'Firmware Version', measurementValue: getSoftVersion(messageValue.substring(2, 6)) }, { measurementId: '3001', type: 'Hardware Version', measurementValue: getHardVersion(messageValue.substring(6, 10)) }, { measurementId: '3940', type: 'Work Mode', measurementValue: getWorkingMode(messageValue.substring(10, 12)) }, { measurementId: '3965', type: 'Positioning Strategy', measurementValue: getPositioningStrategy(messageValue.substring(12, 14)) }, { measurementId: '3942', type: 'Heartbeat Interval', measurementValue: getMinsByMin(messageValue.substring(14, 18)) }, { measurementId: '3943', type: 'Periodic Interval', measurementValue: getMinsByMin(messageValue.substring(18, 22)) }, { measurementId: '3944', type: 'Event Interval', measurementValue: getMinsByMin(messageValue.substring(22, 26)) }, { measurementId: '3945', type: 'Sensor Enable', measurementValue: getInt(messageValue.substring(26, 28)) }, { measurementId: '3941', type: 'SOS Mode', measurementValue: getSOSMode(messageValue.substring(28, 30)) } ] } function getMotionSetting (str) { return [ {measurementId: '3946', type: 'Motion Enable', measurementValue: getInt(str.substring(0, 2))}, {measurementId: '3947', type: 'Any Motion Threshold', measurementValue: getSensorValue(str.substring(2, 6), 1)}, {measurementId: '3948', type: 'Motion Start Interval', measurementValue: getMinsByMin(str.substring(6, 10))}, ] } function getStaticSetting (str) { return [ {measurementId: '3949', type: 'Static Enable', measurementValue: getInt(str.substring(0, 2))}, {measurementId: '3950', type: 'Device Static Timeout', measurementValue: getMinsByMin(str.substring(2, 6))} ] } function getShockSetting (str) { return [ {measurementId: '3951', type: 'Shock Enable', measurementValue: getInt(str.substring(0, 2))}, {measurementId: '3952', type: 'Shock Threshold', measurementValue: getInt(str.substring(2, 6))} ] } function getTempSetting (str) { return [ {measurementId: '3953', type: 'Temp Enable', measurementValue: getInt(str.substring(0, 2))}, {measurementId: '3954', type: 'Event Temp Interval', measurementValue: getMinsByMin(str.substring(2, 6))}, {measurementId: '3955', type: 'Event Temp Sample Interval', measurementValue: getSecondsByInt(str.substring(6, 10))}, {measurementId: '3956', type: 'Temp ThMax', measurementValue: getSensorValue(str.substring(10, 14), 10)}, {measurementId: '3957', type: 'Temp ThMin', measurementValue: getSensorValue(str.substring(14, 18), 10)}, {measurementId: '3958', type: 'Temp Warning Type', measurementValue: getInt(str.substring(18, 20))} ] } function getLightSetting (str) { return [ {measurementId: '3959', type: 'Light Enable', measurementValue: getInt(str.substring(0, 2))}, {measurementId: '3960', type: 'Event Light Interval', measurementValue: getMinsByMin(str.substring(2, 6))}, {measurementId: '3961', type: 'Event Light Sample Interval', measurementValue: getSecondsByInt(str.substring(6, 10))}, {measurementId: '3962', type: 'Light ThMax', measurementValue: getSensorValue(str.substring(10, 14), 10)}, {measurementId: '3963', type: 'Light ThMin', measurementValue: getSensorValue(str.substring(14, 18), 10)}, {measurementId: '3964', type: 'Light Warning Type', measurementValue: getInt(str.substring(18, 20))} ] } function getShardFlag (str) { let bitStr = getByteArray(str) return { count: parseInt(bitStr.substring(0, 4), 2), index: parseInt(bitStr.substring(4), 2) } } function getBattery (batteryStr) { return loraWANV2DataFormat(batteryStr) } function getSoftVersion (softVersion) { return `${loraWANV2DataFormat(softVersion.substring(0, 2))}.${loraWANV2DataFormat(softVersion.substring(2, 4))}` } function getHardVersion (hardVersion) { return `${loraWANV2DataFormat(hardVersion.substring(0, 2))}.${loraWANV2DataFormat(hardVersion.substring(2, 4))}` } function getSecondsByInt (str) { return getInt(str) } function getMinsByMin (str) { return getInt(str) } function getSensorValue (str, dig) { if (str === '8000') { return null } else { return loraWANV2DataFormat(str, dig) } } function bytes2HexString (arrBytes) { var str = '' for (var i = 0; i < arrBytes.length; i++) { var tmp var num = arrBytes[i] if (num < 0) { tmp = (255 + num + 1).toString(16) } else { tmp = num.toString(16) } if (tmp.length === 1) { tmp = '0' + tmp } str += tmp } return str } function loraWANV2DataFormat (str, divisor = 1) { let strReverse = bigEndianTransform(str) let str2 = toBinary(strReverse) if (str2.substring(0, 1) === '1') { let arr = str2.split('') let reverseArr = arr.map((item) => { if (parseInt(item) === 1) { return 0 } else { return 1 } }) str2 = parseInt(reverseArr.join(''), 2) + 1 return '-' + str2 / divisor } return parseInt(str2, 2) / divisor } function bigEndianTransform (data) { let dataArray = [] for (let i = 0; i < data.length; i += 2) { dataArray.push(data.substring(i, i + 2)) } return dataArray } function toBinary (arr) { let binaryData = arr.map((item) => { let data = parseInt(item, 16) .toString(2) let dataLength = data.length if (data.length !== 8) { for (let i = 0; i < 8 - dataLength; i++) { data = `0` + data } } return data }) return binaryData.toString().replace(/,/g, '') } function getSOSMode (str) { return loraWANV2DataFormat(str) } function getMacAndRssiObj (pair) { let pairs = [] if (pair.length % 14 === 0) { for (let i = 0; i < pair.length; i += 14) { let mac = getMacAddress(pair.substring(i, i + 12)) if (mac) { let rssi = getInt8RSSI(pair.substring(i + 12, i + 14)) pairs.push({mac: mac, rssi: rssi}) } else { continue } } } return pairs } function getMacAddress (str) { if (str.toLowerCase() === 'ffffffffffff') { return null } let macArr = [] for (let i = 1; i < str.length; i++) { if (i % 2 === 1) { macArr.push(str.substring(i - 1, i + 1)) } } let mac = '' for (let i = 0; i < macArr.length; i++) { mac = mac + macArr[i] if (i < macArr.length - 1) { mac = mac + ':' } } return mac } function getInt8RSSI (str) { return loraWANV2DataFormat(str) } function getInt (str) { return parseInt(str, 16) } function getEventStatus (str) { // return getInt(str) let bitStr = getByteArray(str) let bitArr = [] for (let i = 0; i < bitStr.length; i++) { bitArr[i] = bitStr.substring(i, i + 1) } bitArr = bitArr.reverse() let event = [] for (let i = 0; i < bitArr.length; i++) { if (bitArr[i] !== '1') { continue } switch (i){ case 0: event.push({id:1, eventName:"Start moving event."}) break case 1: event.push({id:2, eventName:"End movement event."}) break case 2: event.push({id:3, eventName:"Motionless event."}) break case 3: event.push({id:4, eventName:"Shock event."}) break case 4: event.push({id:5, eventName:"Temperature event."}) break case 5: event.push({id:6, eventName:"Light event."}) break case 6: event.push({id:7, eventName:"SOS event."}) break case 7: event.push({id:8, eventName:"Press once event."}) break } } return event } function getByteArray (str) { let bytes = [] for (let i = 0; i < str.length; i += 2) { bytes.push(str.substring(i, i + 2)) } return toBinary(bytes) } function getWorkingMode (workingMode) { return getInt(workingMode) } function getPositioningStrategy (strategy) { return getInt(strategy) } function getUTCTimestamp(str){ return parseInt(loraWANV2PositiveDataFormat(str)) * 1000 } function loraWANV2PositiveDataFormat (str, divisor = 1) { let strReverse = bigEndianTransform(str) let str2 = toBinary(strReverse) return parseInt(str2, 2) / divisor }
This codec is sourced from The Things Network. All rights belong to The Things Network.
This codec is licensed under the GNU General Public License v3 (GPL v3). Modifications, if any, are clearly marked. You are free to use, modify, and distribute the codec under the terms of GPL v3.