{"id":19710,"date":"2026-08-07T11:44:08","date_gmt":"2026-08-07T03:44:08","guid":{"rendered":"https:\/\/www.lansitec.com\/?post_type=docs&#038;p=19710"},"modified":"2026-08-07T11:44:15","modified_gmt":"2026-08-07T03:44:15","password":"","slug":"decoder-lorawan-plug-bluetooth-gateway-ttn-chirpstack","status":"publish","type":"docs","link":"https:\/\/www.lansitec.com\/es\/docs\/decoders\/decoder-lorawan-plug-bluetooth-gateway-ttn-chirpstack\/","title":{"rendered":"Decodificador LoRaWAN: conecte la puerta de enlace Bluetooth (TTN\/Chirpstack)"},"content":{"rendered":"<div class=\"wp-block-file\"><a id=\"wp-block-file--media-76b1e085-b5b2-460a-aee3-9fe7bf75d1f6\" href=\"https:\/\/www.lansitec.com\/wp-content\/uploads\/2026\/08\/decode-plug-bluetooth-gateway-ttn_chirpstackv4.js.zip\">decode-plug-bluetooth-gateway-ttn_chirpstackv4.js<\/a><a href=\"https:\/\/www.lansitec.com\/wp-content\/uploads\/2026\/08\/decode-plug-bluetooth-gateway-ttn_chirpstackv4.js.zip\" class=\"wp-block-file__button wp-element-button\" download aria-describedby=\"wp-block-file--media-76b1e085-b5b2-460a-aee3-9fe7bf75d1f6\">Descargar<\/a><\/div>\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\/\/ Plug Bluetooth Gateway\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 0x04:\n      return { data: decodeRegistration(bytes) };\n\n    case 0x02:\n      return { data: decodeHeartbeat(bytes) };\n\n    case 0x06:\n      return { data: decodeBeacon(bytes) };\n\n    case 0x0e:\n      return { data: decodeAlarmBeaconList(bytes) };\n\n    case 0x0f:\n      return { data: decodeAcknowledgment(bytes) };\n\n    default:\n      return null;\n  }\n}\n\n\/\/ type: 0x4 Registration\nfunction decodeRegistration(bytes) {\n  var data = {};\n  data.type = \"Registration\";\n  \/\/ adr\n  data.adr = ((bytes&#91;0] >> 3) &amp; 0x1) == 0 ? \"OFF\" : \"ON\";\n  \/\/ mode\n  var modeValue = bytes&#91;0] &amp; 0x07;\n  if (modeValue == 0x01) {\n    data.mode = \"AU915\";\n  } else if (modeValue == 0x03) {\n    data.mode = \"CN470\";\n  } else if (modeValue == 0x04) {\n    data.mode = \"AS923\";\n  } else if (modeValue == 0x05) {\n    data.mode = \"EU433\";\n  } else if (modeValue == 0x06) {\n    data.mode = \"EU868\";\n  } else if (modeValue == 0x07) {\n    data.mode = \"US915\";\n  }\n  \/\/ smode\n  var smodeValue = bytes&#91;1];\n  if (smodeValue == 0x01) {\n    data.smode = \"AU915\";\n  } else if (smodeValue == 0x04) {\n    data.smode = \"CN470\";\n  } else if (smodeValue == 0x08) {\n    data.smode = \"AS923\";\n  } else if (smodeValue == 0x10) {\n    data.smode = \"EU433\";\n  } else if (smodeValue == 0x20) {\n    data.smode = \"EU868\";\n  } else if (smodeValue == 0x40) {\n    data.smode = \"US915\";\n  }\n  \/\/ power\n  data.power = ((bytes&#91;2] >> 3) &amp; 0x1f) + \"dBm\";\n  \/\/ continuousBleReceiveEnable\n  data.continuousBleReceiveEnable =\n    ((bytes&#91;2] >> 1) &amp; 0x1) == 0 ? \"Disable\" : \"Enable\";\n  \/\/ powerDownFlag\n  data.powerDownFlag =\n    (bytes&#91;2] &amp; 0x1) == 0 ? \"Normal status\" : \"Automatic shutdown status\";\n  \/\/ dr\n  data.dr = (bytes&#91;3] >> 4) &amp; 0x0f;\n  \/\/ deviceType\n  var deviceType = (bytes&#91;3] >> 1) &amp; 0x02;\n  if (deviceType == 0) {\n    data.deviceType = \"OutdoorGateway\";\n  } else if (deviceType == 1) {\n    data.deviceType = \"IndoorGateway\";\n  } else if (deviceType == 2) {\n    data.deviceType = \"PlugGateway\";\n  }\n  \/\/ rssiSortMethod\n  data.rssiSortMethod =\n    (bytes&#91;3] &amp; 0x01) == 0 ? \"SortByAverage\" : \"SortByTheMaximumValue\";\n  \/\/ positionReportInterval\n  data.positionReportInterval =\n    (((bytes&#91;4] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;5] &amp; 0xff)) * 5 + \"s\";\n  \/\/ bleReceivingDuration\n  data.bleReceivingDuration = bytes&#91;6] * 30 + \"s\";\n  \/\/ heartbeatInterval\n  data.heartbeatInterval = bytes&#91;7] * 30 + \"s\";\n  \/\/ beaconQTY\n  data.beaconQTY = (bytes&#91;8] &amp; 0xff) + \"s\";\n  \/\/ crc\n  data.crc = ((bytes&#91;9] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;10] &amp; 0xff);\n  return data;\n}\n\n\/\/ type: 0x2 Heartbeat\nfunction decodeHeartbeat(bytes) {\n  var data = {};\n  \/\/ type\n  data.type = \"Heartbeat\";\n  \/\/ battery\n  data.battery = bytes&#91;1] + \"%\";\n  \/\/ rssi\n  data.rssi = bytes&#91;2] * -1 + \"dBm\";\n  \/\/ snr\n  data.snr = (((bytes&#91;3] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;4] &amp; 0xff)) \/ 100 + \"dB\";\n  \/\/ version\n  data.version = bytes&#91;5] &amp; 0xff;\n  \/\/ chargeState\n  var chargeState = bytes&#91;6] &amp; 0xff;\n  if (chargeState == 0x00) {\n    data.chargeState = \"Not charging\";\n  } else if (chargeState == 0x50) {\n    data.chargeState = \"Charging\";\n  } else if (chargeState == 0x60) {\n    data.chargeState = \"Charging completed\";\n  }\n  \/\/ crc\n  data.crc = ((bytes&#91;7] &lt;&lt; 8) &amp; 0xff00) | (bytes&#91;8] &amp; 0xff);\n\n  return data;\n}\n\n\/\/ type: 0x6 Beacon\nfunction decodeBeacon(bytes) {\n  var data = {};\n  data.type = \"Beacon\";\n  data.length = bytes&#91;0] &amp; 0x0f;\n  for (let i = 0; i &lt; data.length; i++) {\n    var index = 1 + 6 * i;\n    var uuidTailNumber = bytes&#91;index];\n    var major = ((bytes&#91;index + 1] &lt;&lt; 8) | bytes&#91;index + 2])\n      .toString(16)\n      .toUpperCase()\n      .padStart(4, \"0\");\n    var minor = ((bytes&#91;index + 3] &lt;&lt; 8) | bytes&#91;index + 4])\n      .toString(16)\n      .toUpperCase()\n      .padStart(4, \"0\");\n    var rssi = bytes&#91;index + 5] - 256 + \"dBm\";\n\n    data&#91;\"uuidTailNumber\" + (i + 1)] = uuidTailNumber;\n    data&#91;\"beacon\" + (i + 1)] = major + minor;\n    data&#91;\"rssi\" + (i + 1)] = rssi;\n  }\n\n  return data;\n}\n\n\/\/ type: 0xe AlarmBeaconList\nfunction decodeAlarmBeaconList(bytes) {\n  var data = {};\n  data.type = \"AlarmBeaconList\";\n  data.length = bytes&#91;0] &amp; 0x0f;\n  for (let i = 0; i &lt; data.length; i++) {\n    var index = 1 + 6 * i;\n    var uuidTailNumber = bytes&#91;index];\n    var major = ((bytes&#91;index + 1] &lt;&lt; 8) | bytes&#91;index + 2])\n      .toString(16)\n      .toUpperCase()\n      .padStart(4, \"0\");\n    var minor = ((bytes&#91;index + 3] &lt;&lt; 8) | bytes&#91;index + 4])\n      .toString(16)\n      .toUpperCase()\n      .padStart(4, \"0\");\n    var rssi = bytes&#91;index + 5] - 256 + \"dBm\";\n\n    data&#91;\"uuidTailNumber\" + (i + 1)] = uuidTailNumber;\n    data&#91;\"beacon\" + (i + 1)] = major + minor;\n    data&#91;\"rssi\" + (i + 1)] = rssi;\n  }\n\n  return data;\n}\n\n\/\/ type: 0xf Acknowledgment\nfunction decodeAcknowledgment(bytes) {\n  var data = {};\n  data.type = \"Acknowledgment\";\n  data.result = (bytes&#91;0] &amp; 0x0f) == 0 ? \"Success\" : \"Failure\";\n  data.msgId = (bytes&#91;1] &amp; 0xff).toString(16).toUpperCase();\n\n  return data;\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>","protected":false},"excerpt":{"rendered":"<p>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-19710","docs","type-docs","status-publish","hentry","doc_category-decoders"],"year_month":"2026-08","word_count":589,"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\/19710","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=19710"}],"version-history":[{"count":1,"href":"https:\/\/www.lansitec.com\/es\/wp-json\/wp\/v2\/docs\/19710\/revisions"}],"predecessor-version":[{"id":19712,"href":"https:\/\/www.lansitec.com\/es\/wp-json\/wp\/v2\/docs\/19710\/revisions\/19712"}],"wp:attachment":[{"href":"https:\/\/www.lansitec.com\/es\/wp-json\/wp\/v2\/media?parent=19710"}],"wp:term":[{"taxonomy":"doc_category","embeddable":true,"href":"https:\/\/www.lansitec.com\/es\/wp-json\/wp\/v2\/doc_category?post=19710"},{"taxonomy":"doc_tag","embeddable":true,"href":"https:\/\/www.lansitec.com\/es\/wp-json\/wp\/v2\/doc_tag?post=19710"}],"curies":[{"name":"gracias","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}