{"id":4725,"date":"2021-03-13T11:10:24","date_gmt":"2021-03-13T10:10:24","guid":{"rendered":"http:\/\/bitacora.eniac2000.com\/?p=4725"},"modified":"2021-03-13T11:10:24","modified_gmt":"2021-03-13T10:10:24","slug":"despliegue-de-un-servidor-lorawan-libre-con-chirpstack-basado-en-contenedores","status":"publish","type":"post","link":"https:\/\/bitacora.eniac2000.com\/?p=4725","title":{"rendered":"Despliegue de un servidor LoRaWAN libre con Chirpstack basado en contenedores"},"content":{"rendered":"<p>Estas semanas (en parte por afici\u00f3n y en parte por trabajo) he seguido avanzando con mis investigaciones con tecnolog\u00eda IoT basada en LoRaWAN. Ya hab\u00eda hablado anteriormente de comunicaciones b\u00e1sicas LoRa, uso de una red abierta LoRaWAN como es la red TTN, pero no hab\u00eda tocado el tema de disponer de un servidor LoRaWAN privado. Y es aqu\u00ed donde entra en acci\u00f3n Chirpstack. \u00c9ste es un dise\u00f1o basado en software libre que proporciona la capacidad de conectar dispositivos de campo LoRa y junto con los Gateway LoRaWAN permite constituir una red privada LoRaWAN. En este contexto, ChirpStack una soluci\u00f3n que mediante una interfaz de usuario amigable permite gestionar dispositivos, usuarios, gateways, y que proporciona una interfaz de integraci\u00f3n que permite interactuar con terceros sistemas.<\/p>\n<figure id=\"attachment_4727\" aria-describedby=\"caption-attachment-4727\" style=\"width: 400px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2021\/03\/presentacion-chirpstack.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2021\/03\/presentacion-chirpstack-400x255.png\" alt=\"Interfaz web de administraci\u00f3n de Chirpstack\" title=\"Interfaz web de administraci\u00f3n de Chirpstack\" width=\"400\" height=\"255\" class=\"size-medium wp-image-4727\" \/><\/a><figcaption id=\"caption-attachment-4727\" class=\"wp-caption-text\">Interfaz web de administraci\u00f3n de Chirpstack<\/figcaption><\/figure>\n<p>ChirpStack proporciona una serie de componentes que interact\u00faan entre s\u00ed para proporcionar la infraestructura necesaria para recibir informaci\u00f3n de dispositivos y gateways LoRa, con el objeto de proporcionar capacidades de gesti\u00f3n de dichos dispositivos (por un lado) y de poner la informaci\u00f3n que env\u00edan los dispositivos a disposici\u00f3n de terceros sistemas para que la consuman. Esto se articula en base a los siguientes componentes:<\/p>\n<ul>\n<li><strong>Dispositivos LoRa:<\/strong> Dispositivos de campo que env\u00edan por LoRa informaci\u00f3n de los sistemas que controlan (final de carrera, sensor de temperatura, el propio estado del dispositivo, etc\u2026) a un Gateway, o bien que reciben informaci\u00f3n de este Gateway para realizar una acci\u00f3n (activar un rel\u00e9, encender un led\u2026).<\/li>\n<li><strong>Gateway LoRaWAN:<\/strong> Elemento que recibe informaci\u00f3n de los dispositivos, y transforma un paquete LoRa en un paquete IP (bien TCP o UDP, aunque lo m\u00e1s com\u00fan es lo primero), transfiriendo la informaci\u00f3n que proporciona el dispositivo hacia un servidor donde esta informaci\u00f3n es procesada. Tambi\u00e9n tiene capacidad de enviar informaci\u00f3n o solicitud de acciones a los dispositivos por parte de este servidor. Junto con los dispositivos LoRa, constituyen los elementos de campo, y aunque no forman parte estrictamente hablando de ChirpStack, s\u00ed tienen una interacci\u00f3n muy cercana con \u00e9l.<\/li>\n<li><strong>Gateway Bridge:<\/strong> Es el primero de los componentes de ChirpStack, si seguimos el flujo de datos desde los dispositivos de campo hasta los servidores de computaci\u00f3n. Su funci\u00f3n es recibir la informaci\u00f3n de los gateways y procesarla, volc\u00e1ndola en un servidor MQTT de mensajer\u00eda. Este bridge puede residir en el servidor donde se despliegue ChirpStack, en los propios gateways LoRa  o estar instalado en un tercer componente aparte. Su funci\u00f3n primordial, en pocas palabras, es volcar la informaci\u00f3n proveniente de la red LoRaWAN en el sistema de mensajer\u00eda MQTT, donde ser\u00e1 consumida por el resto de servicios de ChirpStack.<\/li>\n<li><strong>Network Server:<\/strong> Segundo de los componentes de ChirpStack. Es el servidor de red LoRaWAN propiamente dicho. Se encarga de monitorizar el estado de la red, los dispositivos conectados a la misma, y administrar el acceso de nuevos dispositivos a la red. Tambi\u00e9n se encarga, en el caso de redes con m\u00faltiples gateways, de resolver duplicidades de dispositivos (dado que un paquete enviado por un dispositivo puede ser recibido y procesado por m\u00e1s de un Gateway), consolidar la informaci\u00f3n, y ponerla a disposici\u00f3n del servidor de aplicaciones de ChirpStack. Tambi\u00e9n se encarga de las siguientes funcionalidades: Autenticaci\u00f3n de dispositivos; gesti\u00f3n de la capa mac LoRaWAN; gestionar el env\u00edo de mensajes desde ChirpStack a los dispositivos, haciendo uso del canal descendiente de comunicaciones.<\/li>\n<li><strong>Application Server:<\/strong> Tercer componente de ChirpStack. Es coraz\u00f3n de la arquitectura. Permite crear \u201caplicaciones\u201d, que en este contexto son grupos de dispositivos que env\u00edan una informaci\u00f3n del mismo tipo. Relaciona la informaci\u00f3n enviada por uno o varios dispositivos, almacenando un hist\u00f3rico, y la pone a disposici\u00f3n de terceros sistemas mediante diversos m\u00e9todos de integraci\u00f3n.<\/li>\n<li><strong>Geolocation server:<\/strong> Componente opcional que permite dotar de mayores capacidades de geolocalizaci\u00f3n de los dispositivos, en caso de que el Gateway no proporcione esta informaci\u00f3n, o en el que queramos hacer un tratamiento personalizado de la misma.<\/li>\n<li><strong>Broker MQTT:<\/strong> Utilizado como sistema de mensajer\u00eda interna para el resto de componentes de ChirpStack y la comunicaci\u00f3n con los gateways.<\/li>\n<li><strong>Redis:<\/strong> Motor de base de datos en memoria, que gestiona la informaci\u00f3n que se intercambia entre los dispositivos y aplicaciones creadas en ChirpStack.<\/li>\n<li><strong>Base de datos PostgreSQL:<\/strong> Almacena informaci\u00f3n de configuraci\u00f3n de ChirpStack, organizaciones, aplicaciones, usuarios, etc\u2026 adem\u00e1s de informaci\u00f3n hist\u00f3rica enviada por los dispositivos. Existen diversos mecanismos (HTTP, MQTT, InfluxDB, RabbitMQ, PostgreSQL, Azure Service Bus, AWS SNS, API REST).<\/li>\n<\/ul>\n<figure id=\"attachment_4726\" aria-describedby=\"caption-attachment-4726\" style=\"width: 400px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2021\/03\/arquitectura-chirpstack.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2021\/03\/arquitectura-chirpstack-400x137.png\" alt=\"Arquitectura de alto nivel de Chirpstack\" title=\"Arquitectura de alto nivel de Chirpstack\" width=\"400\" height=\"137\" class=\"size-medium wp-image-4726\" \/><\/a><figcaption id=\"caption-attachment-4726\" class=\"wp-caption-text\">Arquitectura de alto nivel de Chirpstack<\/figcaption><\/figure>\n<p>El aspecto clave de ChirpStack hace referencia al modo en el que se procesa la informaci\u00f3n. ChirpStack hace uso de los componentes anteriores para componer y almacenar informaci\u00f3n estructurada proveniente de los dispositivos de campo, en un formato similar al siguiente:<\/p>\n<blockquote><p>{<br \/>\n    \u00abapplicationID\u00bb: \u00ab123\u00bb,<br \/>\n    \u00abapplicationName\u00bb: \u00abtemperature-sensor\u00bb,<br \/>\n    \u00abdeviceName\u00bb: \u00abgarden-sensor\u00bb,<br \/>\n    \u00abdevEUI\u00bb: \u00ab0202020202020202\u00bb,<br \/>\n    \u00abrxInfo\u00bb: [<br \/>\n        {<br \/>\n            \u00abgatewayID\u00bb: \u00ab0303030303030303\u00bb,<br \/>\n            \u00abname\u00bb: \u00abrooftop-gateway\u00bb,<br \/>\n            \u00abtime\u00bb: \u00ab2016-11-25T16:24:37.295915988Z\u00bb,<br \/>\n            \u00abrssi\u00bb: -57,<br \/>\n            \u00abloRaSNR\u00bb: 10,<br \/>\n            \u00ablocation\u00bb: {<br \/>\n                \u00ablatitude\u00bb: 52.3740364,<br \/>\n                \u00ablongitude\u00bb: 4.9144401,<br \/>\n                \u00abaltitude\u00bb: 10.5<br \/>\n            }<br \/>\n        }<br \/>\n    ],<br \/>\n    \u00abtxInfo\u00bb: {<br \/>\n        \u00abfrequency\u00bb: 868100000,<br \/>\n        \u00abdr\u00bb: 5<br \/>\n    },<br \/>\n    \u00abadr\u00bb: false,<br \/>\n    \u00abfCnt\u00bb: 10,<br \/>\n    \u00abfPort\u00bb: 5,<br \/>\n    \u00abdata\u00bb: \u00ab&#8230;\u00bb,<br \/>\n    \u00abobject\u00bb: {<br \/>\n        \u00abtemperatureSensor\u00bb: {\u00ab1\u00bb: 25},<br \/>\n        \u00abhumiditySensor\u00bb: {\u00ab1\u00bb: 32}<br \/>\n    },<br \/>\n    \u00abtags\u00bb: {<br \/>\n        \u00abkey\u00bb: \u00abvalue\u00bb<br \/>\n    }<br \/>\n}\n<\/p><\/blockquote>\n<p>Otro aspecto interesante es que Chirpstack se puede desplegar de muy diversas maneras, al estar estructurado en una serie de componentes bien definidos que se comunican entre ellos mediante puertos e interfaces estandarizados. Permite tanto realizar un despliegue convencional en un \u00fanico servidor, a desplegarse en un modelo de microservicios en un entorno Docker o Kubernetes. Para el caso en el que estoy trabajando, he optado por hacer un despliegue basado en contenedores Docker en una m\u00e1quina virtual, aunque he realizado algunas pruebas con un despliegue m\u00e1s monol\u00edtico, y en el \u00e1mbito laboral estoy haciendo uso de un entorno Kubernetes.<\/p>\n<p>El despliegue mediante Docker es tremendamente sencillo, ya que los propios desarrolladores de Chirpstack proporcionan una <a href=\"https:\/\/github.com\/brocaar\/chirpstack-docker\" target=\"_blank\">configuraci\u00f3n de ejemplo con todos los elementos necesarios<\/a>. Y una vez desplegado, es bastante sencillo a\u00f1adir los componentes necesarios. En mi caso, he integrado un gateway Dragino LG308. La integraci\u00f3n es tan sencilla como apuntar el servicio LoRaWAN del gateway al puerto 1700\/UDP del servidor donde se encuentre levantado el componente Network de Chirpstack. Es posible desplegar un paquete software en el gateway Dragino para convertirlo en un Gateway Bridge de Chirpstack, pero si tenemos \u00e9ste desplegado en otro sitio, no es necesario realizarlo.<\/p>\n<figure id=\"attachment_4728\" aria-describedby=\"caption-attachment-4728\" style=\"width: 400px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2021\/03\/WhatsApp-Image-2021-02-20-at-10.24.32.jpeg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2021\/03\/WhatsApp-Image-2021-02-20-at-10.24.32-400x296.jpeg\" alt=\"Registro de un gateway en Chirpstack\" title=\"Registro de un gateway en Chirpstack\" width=\"400\" height=\"296\" class=\"size-medium wp-image-4728\" \/><\/a><figcaption id=\"caption-attachment-4728\" class=\"wp-caption-text\">Registro de un gateway en Chirpstack<\/figcaption><\/figure>\n<p>Y en cuanto al registro de los dispositivos, tampoco supone mayor inconveniente. Es necesario definir de manera previa unos perfiles de configuraci\u00f3n de dispositivos y la aplicaci\u00f3n donde registramos estos \u00faltimos, y a partir de ah\u00ed, se puede crear la propia aplicaci\u00f3n, y registrar los dispositivos, bien por OTAA o ABP, en funci\u00f3n de nuestras preferencias. Con todo ello, se tiene una red privada LoRaWAN perfectamente funcional.<\/p>\n<figure id=\"attachment_4730\" aria-describedby=\"caption-attachment-4730\" style=\"width: 400px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2021\/03\/WhatsApp-Image-2021-02-20-at-10.27.52.jpeg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2021\/03\/WhatsApp-Image-2021-02-20-at-10.27.52-400x313.jpeg\" alt=\"Ejemplo de recepci\u00f3n de datos de un dispositivo de campo (1)\" title=\"Ejemplo de recepci\u00f3n de datos de un dispositivo de campo (1)\" width=\"400\" height=\"313\" class=\"size-medium wp-image-4730\" \/><\/a><figcaption id=\"caption-attachment-4730\" class=\"wp-caption-text\">Ejemplo de recepci\u00f3n de datos de un dispositivo de campo (1)<\/figcaption><\/figure>\n<figure id=\"attachment_4729\" aria-describedby=\"caption-attachment-4729\" style=\"width: 400px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2021\/03\/WhatsApp-Image-2021-02-20-at-10.24.53.jpeg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/bitacora.eniac2000.com\/wp-content\/uploads\/2021\/03\/WhatsApp-Image-2021-02-20-at-10.24.53-400x292.jpeg\" alt=\"Ejemplo de recepci\u00f3n de datos de un dispositivo de campo (2)\" title=\"Ejemplo de recepci\u00f3n de datos de un dispositivo de campo (2)\" width=\"400\" height=\"292\" class=\"size-medium wp-image-4729\" \/><\/a><figcaption id=\"caption-attachment-4729\" class=\"wp-caption-text\">Ejemplo de recepci\u00f3n de datos de un dispositivo de campo (2)<\/figcaption><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Estas semanas (en parte por afici\u00f3n y en parte por<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[13,25],"tags":[412,447,540,548,909,996,998,1073],"series":[],"class_list":["post-4725","post","type-post","status-publish","format-standard","hentry","category-informatica","category-trabajo","tag-chirpstack","tag-contenedor","tag-docker","tag-dragino","tag-kubernetes","tag-lora","tag-lorawan","tag-microservicio"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/bitacora.eniac2000.com\/index.php?rest_route=\/wp\/v2\/posts\/4725","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bitacora.eniac2000.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bitacora.eniac2000.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bitacora.eniac2000.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/bitacora.eniac2000.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4725"}],"version-history":[{"count":0,"href":"https:\/\/bitacora.eniac2000.com\/index.php?rest_route=\/wp\/v2\/posts\/4725\/revisions"}],"wp:attachment":[{"href":"https:\/\/bitacora.eniac2000.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4725"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bitacora.eniac2000.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4725"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bitacora.eniac2000.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4725"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/bitacora.eniac2000.com\/index.php?rest_route=%2Fwp%2Fv2%2Fseries&post=4725"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}