Skip to main content

Configuración de Mapper TTN

TTN Mapper es una herramienta conveniente utilizada para mapear la cobertura de red de gateways conectados a The Things Stack. Consulta el sitio oficial de documentación de TTN Mapper para más detalles.

Este tutorial guiará a los usuarios para agregar el SenseCAP T1000 Tracker a TTN Mapper.

Para explorar los siguientes pasos, por favor consulta Conectar a The Things Network para registrar tu dispositivo primero.

Configurar los formateadores de carga útil

Crea un Formateador JavaScript personalizado y copia el siguiente código.

pir

Decodificador para TTN Mapper
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 {
if (element.measurementId === '4197') {
decoded.longitude = element.measurementValue
}
if (element.measurementId === '4198') {
decoded.latitude = element.measurementValue
}
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: 'Positioning 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) {
let status = getInt(str)
switch (status) {
case 0:
return {id:status, statusName:"Positioning successful."}
case 1:
return {id:status, statusName:"The GNSS scan timed out and failed to obtain the location."}
case 2:
return {id:status, statusName:"The Wi-Fi scan timed out and failed to obtain the location."}
case 3:
return {id:status, statusName:"The Wi-Fi + GNSS scan timed out and failed to obtain the location."}
case 4:
return {id:status, statusName:"The GNSS + Wi-Fi scan timed out and failed to obtain the location."}
case 5:
return {id:status, statusName:"The Bluetooth scan timed out and failed to obtain the location."}
case 6:
return {id:status, statusName:"The Bluetooth + Wi-Fi scan timed out and failed to obtain the location."}
case 7:
return {id:status, statusName:"The Bluetooth + GNSS scan timed out and failed to obtain the location."}
case 8:
return {id:status, statusName:"The Bluetooth + Wi-Fi + GNSS scan timed out and failed to obtain the location."}
case 9:
return {id:status, statusName:"Location Server failed to parse the GNSS location."}
case 10:
return {id:status, statusName:"Location Server failed to parse the Wi-Fi location."}
case 11:
return {id:status, statusName:"Location Server failed to parse the Bluetooth location."}
case 12:
return {id:status, statusName:"Failed to parse the GNSS location due to the poor accuracy."}
case 13:
return {id:status, statusName:"Time synchronization failed."}
case 14:
return {id:status, statusName:"Failed to obtain location due to the old Almanac."}
}
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
}

Añadir plantilla de Webhook

Navega a Integrations -> Webhooks, luego selecciona TTN Mapper.

pir

Asigna un nombre a tu integración completando el campo Webhook ID.

Completa el campo Email address con un email válido, necesario para que tus datos sean aceptados por TTN Mapper. Todos los datos enviados por tu dispositivo final serán asociados a esta dirección de email y proporcionará algunas garantías de la calidad de los datos.

Para leer más sobre experimentos, lee la sección Experiments aquí.

Finaliza haciendo clic en el botón Create TTN Mapper webhook.

pir

Observar La Cobertura de Red

Navega a TTN Mapper y selecciona Advanced Maps en el menú superior.

En la sección Device data, completa el campo Device ID con el ID del dispositivo de The Things Stack.
Elige hoy como Start Date y End Date.
Haz clic en el botón View Map para ver los puntos de datos provenientes de los datos de uplink de tu dispositivo final.

pir

pir

Loading Comments...