{"id":19715,"date":"2026-08-07T12:10:44","date_gmt":"2026-08-07T04:10:44","guid":{"rendered":"https:\/\/www.lansitec.com\/?post_type=docs&#038;p=19715"},"modified":"2026-08-07T13:39:45","modified_gmt":"2026-08-07T05:39:45","password":"","slug":"decoder-lte-badge-tracker","status":"publish","type":"docs","link":"https:\/\/www.lansitec.com\/es\/docs\/decoders\/decoder-lte-badge-tracker\/","title":{"rendered":"Decodificador LTE: rastreador de credenciales y sistema de gesti\u00f3n de activos."},"content":{"rendered":"<div class=\"wp-block-file\"><a id=\"wp-block-file--media-2c5678a8-0e16-43b3-9360-27fdd20f1e22\" href=\"https:\/\/www.lansitec.com\/wp-content\/uploads\/2026\/08\/decode-lte-badgeasset-tracker.js.zip\">decode-lte-badge&#038;asset-tracker.js<\/a><a href=\"https:\/\/www.lansitec.com\/wp-content\/uploads\/2026\/08\/decode-lte-badgeasset-tracker.js.zip\" class=\"wp-block-file__button wp-element-button\" download aria-describedby=\"wp-block-file--media-2c5678a8-0e16-43b3-9360-27fdd20f1e22\">Descargar<\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Note: this decoder is made for MQTT protocol. If you want to integrate our devices with Thingsboard, http or other custom protocols, you can adapt the code below or contact us. We will support you and send you the specific decoder.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Below the full decoder code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Decode uplink function.\n\/\/\n\/\/ Input is an object with the following fields:\n\/\/ - bytes = Byte array containing the uplink payload, e.g. &#91;255, 230, 255, 0]\n\/\/ - fPort = Uplink fPort.\n\/\/ - variables = Object containing the configured device variables.\n\/\/\n\/\/ Output must be an object with the following fields:\n\/\/ - data = Object representing the decoded payload.\n\n\/\/ NB-IoT Badge Tracker\nfunction decodeUplink(input) {\n  \/\/ bytes\n  var bytes = input.bytes;\n  \/\/ type\n  var uplinkType = (bytes&#91;0] >> 4) &amp; 0x0f;\n\n  switch (uplinkType) {\n    case 0x01:\n      return { data: decodeRegistration(bytes) };\n\n    case 0x02:\n      return { data: decodeHeartbeat(bytes) };\n\n    case 0x03:\n      return { data: decodeGNSSPosition(bytes) };\n\n    case 0x04:\n      return { data: decodeBeacon(bytes) };\n\n    case 0x05:\n      return { data: decodeAlarm(bytes) };\n\n    case 0x06:\n      return { data: decodeConfigParameterResponse(bytes) };\n\n    default:\n      return;\n  }\n}\n\n\/\/ type: 0x1 Registration\nfunction decodeRegistration(bytes) {\n  var data = {};\n  data.type = \"RegistrationMessage\";\n  data.bleEnable = (bytes&#91;1] >> 7) &amp; 0x01;\n  data.gnssEnable = (bytes&#91;1] >> 6) &amp; 0x01;\n  data.networkStatusCheckEnable = (bytes&#91;1] >> 5) &amp; 0x01;\n  data.powerSwitchEnable = (bytes&#91;1] >> 4) &amp; 0x01;\n  data.assetBeaconSortEnable = (bytes&#91;1] >> 1) &amp; 0x01;\n  data.gnssFailureReportEnable = bytes&#91;1] &amp; 0x01;\n  data.assetManagementEnable = (bytes&#91;2] >> 7) &amp; 0x01;\n\n  var positionReportMode = (bytes&#91;3] >> 6) &amp; 0x0f;\n  if (positionReportMode == 0) {\n    data.positionReportMode = \"Period\";\n  } else if (positionReportMode == 1) {\n    data.positionReportMode = \"Autonomous\";\n  } else if (positionReportMode == 2) {\n    data.positionReportMode = \"On-demand\";\n  }\n  data.tamperDetectionEnable = (bytes&#91;3] >> 3) &amp; 0x01;\n\n  data.heartbeatPeriod =\n    (((bytes&#91;6] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;7] &amp; 0xff)) * 30 + \"s\";\n\n  data.blePositionReportInterval =\n    (((bytes&#91;8] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;9] &amp; 0xff)) * 5 + \"s\";\n\n  data.blePositionBeaconReceivingDuration = bytes&#91;10] &amp; 0xff;\n\n  data.gnssPositionReportInterval =\n    (((bytes&#91;11] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;12] &amp; 0xff)) * 5 + \"s\";\n\n  data.gnssReceivingDuration = (bytes&#91;13] &amp; 0xff) * 5 + \"s\";\n\n  data.assetBeaconReportInterval =\n    (((bytes&#91;14] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;15] &amp; 0xff)) * 5 + \"s\";\n\n  data.assetBeaconReceivingDuration = bytes&#91;16] &amp; 0xff;\n\n  data.version = ((bytes&#91;17] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;18] &amp; 0xff);\n\n  var imsi = \"\";\n  for (let i = 0; i &lt; 8; i++) {\n    imsi += bytes&#91;19 + i].toString(16).toUpperCase().padStart(2, \"0\");\n  }\n  data.imsi = imsi.substring(0, 15);\n  data.messageId = ((bytes&#91;27] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;28] &amp; 0xff);\n  return data;\n}\n\n\/\/ type: 0x2 Heartbeat\nfunction decodeHeartbeat(bytes) {\n  var data = {};\n  data.type = \"HeartbeatMessage\";\n  var stateBitField = {};\n  stateBitField.bleEnable = (bytes&#91;1] >> 7) &amp; 0x01;\n  stateBitField.gnssEnable = (bytes&#91;1] >> 6) &amp; 0x01;\n  stateBitField.networkStatusCheckEnable = (bytes&#91;1] >> 5) &amp; 0x01;\n  stateBitField.powerSwitchEnable = (bytes&#91;1] >> 4) &amp; 0x01;\n  stateBitField.assetBeaconSortEnable = (bytes&#91;1] >> 1) &amp; 0x01;\n  stateBitField.gnssFailureReportEnable = bytes&#91;1] &amp; 0x01;\n  stateBitField.assetManagementEnable = (bytes&#91;2] >> 7) &amp; 0x01;\n  var positionReportMode = (bytes&#91;3] >> 6) &amp; 0x0f;\n  if (positionReportMode == 0) {\n    stateBitField.positionReportMode = \"Period\";\n  } else if (positionReportMode == 1) {\n    stateBitField.positionReportMode = \"Autonomous\";\n  } else if (positionReportMode == 2) {\n    stateBitField.positionReportMode = \"On-demand\";\n  }\n  stateBitField.tamperDetectionEnable = (bytes&#91;3] >> 3) &amp; 0x01;\n  data.stateBitField = stateBitField;\n\n  data.batteryVoltage = ((bytes&#91;5] &amp; 0xff) * 0.01 + 2.00) + \"V\";\n  data.batteryLevel = (bytes&#91;6] &amp; 0xff) + \"%\";\n  data.bleReceivingCount = bytes&#91;7] &amp; 0xff;\n  data.gnssOnCount = bytes&#91;8] &amp; 0xff;\n  \/\/ temperature\n  if (0 == ((bytes&#91;9] >> 7) &amp; 0x01)) {\n    data.temperature = (((bytes&#91;9] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;10] &amp; 0xff)) + \"\u00b0C\";\n  } else {\n    data.temperature =\n      (((bytes&#91;9] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;10] &amp; 0xff)) * -1 + \"\u00b0C\";\n  }\n  data.movementDuration =\n    (((bytes&#91;11] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;12] &amp; 0xff)) * 5 + \"s\";\n  data.chargeDuration = ((bytes&#91;15] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;16] &amp; 0xff);\n  data.messageId = ((bytes&#91;17] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;18] &amp; 0xff);\n  return data;\n}\n\n\/\/ type: 0x03 GNSSPosition\nfunction decodeGNSSPosition(bytes) {\n  var data = {};\n  data.type = \"GNSSPosition\";\n  \/\/ longitude\n  let longitude =\n    (bytes&#91;1] &lt;&lt; 24) | (bytes&#91;2] &lt;&lt; 16) | (bytes&#91;3] &lt;&lt; 8) | bytes&#91;4];\n  data.longitude = hex2float(longitude);\n\n  \/\/ latitude\n  let latitude =\n    (bytes&#91;5] &lt;&lt; 24) | (bytes&#91;6] &lt;&lt; 16) | (bytes&#91;7] &lt;&lt; 8) | bytes&#91;8];\n  data.latitude = hex2float(latitude);\n\n  \/\/ time\n  let time =\n    (bytes&#91;9] &lt;&lt; 24) | (bytes&#91;10] &lt;&lt; 16) | (bytes&#91;11] &lt;&lt; 8) | bytes&#91;12];\n  data.time = timestampToTime((time + 8 * 60 * 60) * 1000);\n\n  return data;\n}\n\n\/\/ type: 0x4 Beacon\nfunction decodeBeacon(bytes) {\n  var data = {};\n  data.type = \"BeaconMessage\";\n  data.beaconType =\n    (bytes&#91;0] &amp; 0x01) == 0 ? \"PositioningBeacon\" : \"AssetBeacon\";\n  data.beaconCount = bytes&#91;1] &amp; 0x0f;\n  for (let i = 0; i &lt; data.beaconCount; i++) {\n    var index = 2 + 5 * i;\n    var major = (((bytes&#91;index] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;index + 1] &amp; 0xff))\n      .toString(16)\n      .toUpperCase()\n      .padStart(4, \"0\");\n    var minor = (((bytes&#91;index + 2] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;index + 3] &amp; 0xff))\n      .toString(16)\n      .toUpperCase()\n      .padStart(4, \"0\");\n    var <a href=\"https:\/\/www.lansitec.com\/blogs\/rssi-indoor-positioning\/\">rssi<\/a> = bytes&#91;index + 4] - 256 + \"dBm\";\n\n    data&#91;\"beacon\" + (i + 1)] = major + minor;\n    data&#91;\"<a href=\"https:\/\/www.lansitec.com\/blogs\/rssi-indoor-positioning\/\">rssi<\/a>\" + (i + 1)] = <a href=\"https:\/\/www.lansitec.com\/blogs\/rssi-indoor-positioning\/\">rssi<\/a>;\n  }\n\n  return data;\n}\n\n\/\/ type: 0x5 Alarm\nfunction decodeAlarm(bytes) {\n  var data = {};\n  data.type = \"AlarmMessage\";\n  var alarmValue = bytes&#91;1] &amp; 0x0f;\n  if (alarmValue == 1) {\n    data.alarm = \"SOS\";\n  } else if (alarmValue == 2) {\n    data.alarm = \"Fall\";\n  }\n  return data;\n}\n\n\/\/ type: 0x6 Configuration Parameter Response\nfunction decodeConfigParameterResponse(bytes) {\n  var data = {};\n  data.type = \"ConfigurationParameterResponse\";\n  var parameter = &#91;];\n  let byteLength = bytes.length;\n  var index = 0;\n  while (index + 1 &lt; byteLength) {\n    var commandBitField = {};\n    var parameterType = bytes&#91;index + 1] &amp; 0xff;\n    commandBitField.parameterType = parameterType;\n    var commandBitFieldLength = getCommandBitFieldLength(parameterType);\n    var parameterValue = getParameterValue(bytes, index, commandBitFieldLength);\n    commandBitField.parameterValue = parameterValue;\n    commandBitField.name = getParameterName(parameterType);\n    commandBitField.parameterDefinition = getParameterDefinition(\n      parameterType,\n      parameterValue\n    );\n    index = index + commandBitFieldLength;\n    parameter.push(commandBitField);\n  }\n  data.parameter = parameter;\n  return data;\n}\n\n\/\/ getParameterValue hexString\nfunction getParameterValue(bytes, index, length) {\n  var hexString = \"\";\n  for (var i = 2; i &lt;= length; i++) {\n    var hex = (bytes&#91;index + i] &amp; 0xff).toString(16).toUpperCase();\n    hexString += hex.padStart(2, \"0\");\n  }\n  return hexString;\n}\n\n\/\/ getCommandBitFieldLength\nfunction getCommandBitFieldLength(parameterType) {\n  let lengths = {\n    0x00: 3,\n    0x01: 3,\n    0x02: 3,\n    0x03: 3,\n    0x04: 3,\n    0x05: 2,\n    0x06: 2,\n    0x07: 2,\n    0x08: 2,\n    0x0a: 17,\n    0x0b: 17,\n    0x0e: 9,\n    0x1e: 2,\n    0x1f: 2,\n    0x20: 2,\n    0x29: 2,\n    0x2a: 2,\n    0x2b: 2,\n    0x2e: 2,\n    0x2f: 2,\n    0x30: 2,\n    0x31: 2,\n  };\n  return lengths&#91;parameterType] ?? 0;\n}\n\n\/\/ Parameter Name\nfunction getParameterName(parameterType) {\n  let name = {\n    0x00: \"SoftwareVersion\",\n    0x01: \"HBPeriod\",\n    0x02: \"BlePositionReportInterval\",\n    0x03: \"GNSSPositionReportInterval\",\n    0x04: \"AssetBeaconReportInterval\",\n    0x05: \"BlePositionReceivingDuration\",\n    0x06: \"GNSSPositionReceivingDuration\",\n    0x07: \"AssetBleReceivingDuration\",\n    0x08: \"FallThreshold\",\n    0x0a: \"PosBeaconUUID\",\n    0x0b: \"AssetBeaconUUID\",\n    0x0e: \"ISMI\",\n    0x1e: \"FallDetectionAlarmEnable\",\n    0x1f: \"SOSAlarmEnable\",\n    0x20: \"PosMode\",\n    0x29: \"AssetManagementEnable\",\n    0x2a: \"GNSSFailureReportEnable\",\n    0x2b: \"AssetBeaconSortEnable\",\n    0x2e: \"PowerSwitchEnable\",\n    0x2f: \"NetworkStatusCheck\",\n    0x30: \"GNSSEnableState\",\n    0x31: \"BleEnable\",\n  };\n  return name&#91;parameterType] ?? \"No matching parameter names\";\n}\n\n\/\/ Parameter Definition\nfunction getParameterDefinition(parameterType, parameterValue) {\n  var val = parseInt(parameterValue, 16);\n  let name = {\n    0x00: \"SoftwareVersion\",\n    0x01: val * 30 + \"s, The interval of the heartbeat message, unit: 30s\",\n    0x02: val * 5 + \"s, The interval of Bluetooth position repor, unit: 5s\",\n    0x03: val * 5 + \"s, The interval of GNSS position report, unit: 5s\",\n    0x04: val * 5 + \"s, The interval of asset beacons report, unit: 5s\",\n    0x05:\n      val * 1 + \"s, The duration of BLE position beacon receiving, unit: 1s\",\n    0x06: val * 5 + \"s, The duration of GNSS position receiving, unit: 5s\",\n    0x07: val * 1 + \"s, The duration of asset beacon receiving, unit 1s\",\n    0x08:\n      val \/ 2 +\n      \"s, The threshold of the fall detection, the unit is 0.5 meters\",\n    0x0a: \"PosBeaconUUIDFilter\",\n    0x0b: \"AssetBeaconUUIDFilter\",\n    0x0e: \"ISMI\",\n    0x1e: val == 0 ? \"Disable\" : \"Enable\",\n    0x1f: val == 0 ? \"Disable\" : \"Enable\",\n    0x20:\n      val == 0\n        ? \"Period Mode\"\n        : val == 1\n        ? \" Autonomous Mode\"\n        : \"On-demand Mode\",\n    0x29: val == 0 ? \"Disable\" : \"Enable\",\n    0x2a: val == 0 ? \"Disable\" : \"Enable\",\n    0x2b: val == 0 ? \"Disable\" : \"Enable\",\n    0x2e: val == 0 ? \"Disable\" : \"Enable\",\n    0x2f: val == 0 ? \"Disable\" : \"Enable\",\n    0x30: val == 0 ? \"Disable\" : \"Enable\",\n    0x31: val == 0 ? \"Disable\" : \"Enable\",\n  };\n  return name&#91;parameterType] ?? \"No matching parameter names\";\n}\n\n\/\/ Floating point conversion\nfunction hex2float(num) {\n  var sign = num &amp; 0x80000000 ? -1 : 1;\n  var exponent = ((num >> 23) &amp; 0xff) - 127;\n  var mantissa = 1 + (num &amp; 0x7fffff) \/ 0x7fffff;\n  return sign * mantissa * Math.pow(2, exponent);\n}\n\nfunction asciiToHex(str) {\n  var hexString = \"\";\n  for (let i = 0; i &lt; str.length; i++) {\n    var hex = str.charCodeAt(i).toString(16);\n    hexString += hex.padStart(2, \"0\");\n  }\n  return hexString;\n}\n\nfunction hexStringToByteArray(hexString) {\n  var byteArray = &#91;];\n  for (let i = 0; i &lt; hexString.length; i += 2) {\n    byteArray.push(parseInt(hexString.substr(i, 2), 16));\n  }\n  return new Uint8Array(byteArray);\n}\n\nfunction timestampToTime(timestamp) {\n  const date = new Date(timestamp);\n  const year = date.getFullYear();\n  const month = (date.getMonth() + 1).toString().padStart(2, \"0\");\n  const day = date.getDate().toString().padStart(2, \"0\");\n  const hour = date.getHours().toString().padStart(2, \"0\");\n  const minute = date.getMinutes().toString().padStart(2, \"0\");\n  const second = date.getSeconds().toString().padStart(2, \"0\");\n  return `${year}-${month}-${day} ${hour}:${minute}:${second}`;\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>","protected":false},"excerpt":{"rendered":"<p>Note: this decoder is made for MQTT protocol. If you want to integrate our devices with Thingsboard, http or other custom protocols, you can adapt the code below or contact us. We will support you and send you the specific decoder. Below the full decoder code:<\/p>","protected":false},"author":5,"featured_media":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","footnotes":""},"doc_category":[338],"doc_tag":[],"class_list":["post-19715","docs","type-docs","status-publish","hentry","doc_category-decoders"],"year_month":"2026-08","word_count":1180,"total_views":"22","reactions":{"happy":"0","normal":"0","sad":"0"},"author_info":{"name":"Ma\u00edz","author_nicename":"maizi","author_url":"https:\/\/www.lansitec.com\/es\/author\/maizi\/"},"doc_category_info":[{"term_name":"Decoders","term_url":"https:\/\/www.lansitec.com\/es\/doc\/decoders\/"}],"doc_tag_info":[],"knowledge_base_info":[],"knowledge_base_slug":[],"_links":{"self":[{"href":"https:\/\/www.lansitec.com\/es\/wp-json\/wp\/v2\/docs\/19715","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lansitec.com\/es\/wp-json\/wp\/v2\/docs"}],"about":[{"href":"https:\/\/www.lansitec.com\/es\/wp-json\/wp\/v2\/types\/docs"}],"author":[{"embeddable":true,"href":"https:\/\/www.lansitec.com\/es\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lansitec.com\/es\/wp-json\/wp\/v2\/comments?post=19715"}],"version-history":[{"count":3,"href":"https:\/\/www.lansitec.com\/es\/wp-json\/wp\/v2\/docs\/19715\/revisions"}],"predecessor-version":[{"id":19727,"href":"https:\/\/www.lansitec.com\/es\/wp-json\/wp\/v2\/docs\/19715\/revisions\/19727"}],"wp:attachment":[{"href":"https:\/\/www.lansitec.com\/es\/wp-json\/wp\/v2\/media?parent=19715"}],"wp:term":[{"taxonomy":"doc_category","embeddable":true,"href":"https:\/\/www.lansitec.com\/es\/wp-json\/wp\/v2\/doc_category?post=19715"},{"taxonomy":"doc_tag","embeddable":true,"href":"https:\/\/www.lansitec.com\/es\/wp-json\/wp\/v2\/doc_tag?post=19715"}],"curies":[{"name":"gracias","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}