{"id":19912,"date":"2026-08-11T18:35:07","date_gmt":"2026-08-11T10:35:07","guid":{"rendered":"https:\/\/www.lansitec.com\/?post_type=docs&#038;p=19912"},"modified":"2026-08-11T18:39:36","modified_gmt":"2026-08-11T10:39:36","password":"","slug":"decoder-ntn-livestock-solar-eartag-tracker","status":"publish","type":"docs","link":"https:\/\/www.lansitec.com\/es\/docs\/decoders\/decodificador-ntn-rastreador-solar-de-etiquetas-auriculares-para-ganado\/","title":{"rendered":"Decodificador NTN \u2013 Rastreador solar de etiquetas auriculares para ganado"},"content":{"rendered":"<div class=\"wp-block-file\"><a id=\"wp-block-file--media-f31b12ea-df42-495f-9d26-34fa018f8d4b\" href=\"https:\/\/www.lansitec.com\/wp-content\/uploads\/2026\/08\/decode-livestock-tag-tracker-ntn-udp.zip\">decode-livestock-tag-tracker-ntn-udp<\/a><a href=\"https:\/\/www.lansitec.com\/wp-content\/uploads\/2026\/08\/decode-livestock-tag-tracker-ntn-udp.zip\" class=\"wp-block-file__button wp-element-button\" download aria-describedby=\"wp-block-file--media-f31b12ea-df42-495f-9d26-34fa018f8d4b\">Descargar<\/a><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Para crear autom\u00e1ticamente mensajes de enlace ascendente y descendente, consulte esta p\u00e1gina:<br><a href=\"https:\/\/www.lansitec.com\/es\/lansitec-decoder-live-calculator\/\">Lansitec Decoder \u2013 Live Calculator \u2013 Lansitec<\/a><br><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A continuaci\u00f3n se muestra el c\u00f3digo completo del decodificador:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Lansitec <a href=\"https:\/\/www.lansitec.com\/fr\/produits\/etiquette-de-suivi-du-betail-ntn\/\">NTN Livestock Tracking Tag<\/a> - <a href=\"https:\/\/www.lansitec.com\/fr\/blogs\/reseaux-non-terrestres-ntn-connectivite-par-satellite-pour-le-suivi\/\">NTN<\/a> UDP Status Report decoder.\n\/\/\n\/\/ The UDP server must pass the raw 21-byte datagram payload, not a printable\n\/\/ hexadecimal string:\n\/\/   decodeNtn({ bytes: &#91;...] })\n\/\/   decodeNtn(Buffer.from(...))\n\n\"use strict\";\n\nfunction decodeNtn(input) {\n  var normalized = normalizeBytes(input);\n  if (normalized.error) {\n    return errorResult(normalized.error);\n  }\n\n  var bytes = normalized.bytes;\n  if (bytes.length !== 21) {\n    return errorResult(\"<a href=\"https:\/\/www.lansitec.com\/fr\/blogs\/reseaux-non-terrestres-ntn-connectivite-par-satellite-pour-le-suivi\/\">NTN<\/a> Status Report must be exactly 21 bytes; received \" + bytes.length + \".\");\n  }\n\n  if (bytes&#91;0] !== 0x01) {\n    return errorResult(\"Unsupported <a href=\"https:\/\/www.lansitec.com\/fr\/blogs\/reseaux-non-terrestres-ntn-connectivite-par-satellite-pour-le-suivi\/\">NTN<\/a> payload version: \" + toHex(bytes&#91;0], 2) + \".\");\n  }\n\n  var batteryRaw = bytes&#91;5];\n  if (batteryRaw &gt; 100 &amp;&amp; batteryRaw !== 0xff) {\n    return errorResult(\"<a href=\"https:\/\/www.lansitec.com\/fr\/blogs\/reseaux-non-terrestres-ntn-connectivite-par-satellite-pour-le-suivi\/\">NTN<\/a> battery value must be between 0 and 100, or 0xFF when unavailable.\");\n  }\n\n  var alarmRaw = bytes&#91;8];\n  if ((alarmRaw &amp; 0xf0) !== 0) {\n    return errorResult(\"<a href=\"https:\/\/www.lansitec.com\/fr\/blogs\/reseaux-non-terrestres-ntn-connectivite-par-satellite-pour-le-suivi\/\">NTN<\/a> Alarm Flags RFU bits 7 to 4 must be zero.\");\n  }\n\n  var longitude = readFloat32BE(bytes, 9);\n  var latitude = readFloat32BE(bytes, 13);\n  var positionAvailable = !(longitude === 0 &amp;&amp; latitude === 0);\n\n  if (!isFiniteNumber(longitude) || longitude &lt; -180 || longitude &gt; 180) {\n    return errorResult(\"<a href=\"https:\/\/www.lansitec.com\/fr\/blogs\/reseaux-non-terrestres-ntn-connectivite-par-satellite-pour-le-suivi\/\">NTN<\/a> longitude must be a finite value in the range -180 to 180 degrees.\");\n  }\n  if (!isFiniteNumber(latitude) || latitude &lt; -90 || latitude &gt; 90) {\n    return errorResult(\"<a href=\"https:\/\/www.lansitec.com\/fr\/blogs\/reseaux-non-terrestres-ntn-connectivite-par-satellite-pour-le-suivi\/\">NTN<\/a> latitude must be a finite value in the range -90 to 90 degrees.\");\n  }\n\n  var timestamp = readUInt32BE(bytes, 17);\n  var activeAlarms = &#91;];\n  if ((alarmRaw &amp; 0x01) !== 0) activeAlarms.push(\"lowBattery\");\n  if ((alarmRaw &amp; 0x02) !== 0) activeAlarms.push(\"fenceBreach\");\n  if ((alarmRaw &amp; 0x04) !== 0) activeAlarms.push(\"abnormalInactivity\");\n  if ((alarmRaw &amp; 0x08) !== 0) activeAlarms.push(\"highIntensityMotion\");\n\n  var data = {\n    transport: \"NTN_UDP\",\n    messageName: \"statusReport\",\n    payloadVersion: bytes&#91;0],\n    deviceId: toHex(readUInt32BE(bytes, 1), 8),\n    deviceIdNumeric: readUInt32BE(bytes, 1),\n    batteryAvailable: batteryRaw !== 0xff,\n    batteryPercent: batteryRaw === 0xff ? null : batteryRaw,\n    motionDurationSeconds: readUInt16BE(bytes, 6),\n    alarmFlags: {\n      raw: alarmRaw,\n      lowBattery: (alarmRaw &amp; 0x01) !== 0,\n      fenceBreach: (alarmRaw &amp; 0x02) !== 0,\n      abnormalInactivity: (alarmRaw &amp; 0x04) !== 0,\n      highIntensityMotion: (alarmRaw &amp; 0x08) !== 0,\n      active: activeAlarms,\n    },\n    positionAvailable: positionAvailable,\n    longitude: positionAvailable ? longitude : null,\n    latitude: positionAvailable ? latitude : null,\n    timestampAvailable: timestamp !== 0,\n    timestamp: timestamp === 0 ? null : timestamp,\n    timestampIso: timestamp === 0 ? null : unixTimeToIso(timestamp),\n    payloadHex: bytesToHex(bytes),\n  };\n\n  return { data: data };\n}\n\nfunction normalizeBytes(input) {\n  var source = input &amp;&amp; typeof input === \"object\" &amp;&amp; input.bytes !== undefined ? input.bytes : input;\n  if (!source || typeof source === \"string\" || typeof source.length !== \"number\") {\n    return { error: \"Input must be a raw byte array, Uint8Array, or Buffer. Plain-text HEX is not accepted.\" };\n  }\n\n  var bytes = &#91;];\n  for (var i = 0; i &lt; source.length; i++) {\n    var value = source&#91;i];\n    if (typeof value !== \"number\" || !isFinite(value) || Math.floor(value) !== value || value &lt; 0 || value &gt; 255) {\n      return { error: \"Payload byte at index \" + i + \" is not an unsigned 8-bit integer.\" };\n    }\n    bytes.push(value);\n  }\n  return { bytes: bytes };\n}\n\nfunction readUInt16BE(bytes, offset) {\n  return bytes&#91;offset] * 0x100 + bytes&#91;offset + 1];\n}\n\nfunction readUInt32BE(bytes, offset) {\n  return (\n    bytes&#91;offset] * 0x1000000 +\n    bytes&#91;offset + 1] * 0x10000 +\n    bytes&#91;offset + 2] * 0x100 +\n    bytes&#91;offset + 3]\n  );\n}\n\nfunction readFloat32BE(bytes, offset) {\n  var bits = readUInt32BE(bytes, offset);\n  var sign = bits &gt;= 0x80000000 ? -1 : 1;\n  var exponent = Math.floor(bits \/ 0x800000) &amp; 0xff;\n  var fraction = bits &amp; 0x7fffff;\n\n  if (exponent === 0xff) {\n    return fraction === 0 ? sign * Infinity : NaN;\n  }\n  if (exponent === 0) {\n    return sign * fraction * Math.pow(2, -149);\n  }\n  return sign * (1 + fraction \/ 0x800000) * Math.pow(2, exponent - 127);\n}\n\nfunction unixTimeToIso(seconds) {\n  return new Date(seconds * 1000).toISOString();\n}\n\nfunction bytesToHex(bytes) {\n  var parts = &#91;];\n  for (var i = 0; i &lt; bytes.length; i++) {\n    parts.push(toHex(bytes&#91;i], 2).slice(2));\n  }\n  return parts.join(\"\");\n}\n\nfunction isFiniteNumber(value) {\n  return typeof value === \"number\" &amp;&amp; isFinite(value);\n}\n\nfunction toHex(value, width) {\n  var text = Number(value).toString(16).toUpperCase();\n  while (text.length &lt; width) {\n    text = \"0\" + text;\n  }\n  return \"0x\" + text;\n}\n\nfunction errorResult(message) {\n  return { errors: &#91;message] };\n}\n\nif (typeof module !== \"undefined\" &amp;&amp; module.exports) {\n  module.exports = {\n    decodeNtn: decodeNtn,\n  };\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>","protected":false},"excerpt":{"rendered":"<p>To create automatically uplink and downlink messages, please refer to this page:Lansitec Decoder \u2013 Live Calculator \u2013 Lansitec Below the full decoder code:<\/p>","protected":false},"author":5,"featured_media":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"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-19912","docs","type-docs","status-publish","hentry","doc_category-decoders"],"acf":[],"year_month":"2026-08","word_count":571,"total_views":"6","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\/decodificadores\/"}],"doc_tag_info":[],"knowledge_base_info":[],"knowledge_base_slug":[],"_links":{"self":[{"href":"https:\/\/www.lansitec.com\/es\/wp-json\/wp\/v2\/docs\/19912","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=19912"}],"version-history":[{"count":2,"href":"https:\/\/www.lansitec.com\/es\/wp-json\/wp\/v2\/docs\/19912\/revisions"}],"predecessor-version":[{"id":19918,"href":"https:\/\/www.lansitec.com\/es\/wp-json\/wp\/v2\/docs\/19912\/revisions\/19918"}],"wp:attachment":[{"href":"https:\/\/www.lansitec.com\/es\/wp-json\/wp\/v2\/media?parent=19912"}],"wp:term":[{"taxonomy":"doc_category","embeddable":true,"href":"https:\/\/www.lansitec.com\/es\/wp-json\/wp\/v2\/doc_category?post=19912"},{"taxonomy":"doc_tag","embeddable":true,"href":"https:\/\/www.lansitec.com\/es\/wp-json\/wp\/v2\/doc_tag?post=19912"}],"curies":[{"name":"gracias","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}