Ir al contenido principal
Todas las coleccionesRecursos técnicos
Decodificadores de Ubidots como Servicio
Decodificadores de Ubidots como Servicio

Ejecuta decodificadores de Javascript públicos utilizando nuestra API pública DaaS (Decodificadores como Servicio)

Sergio M avatar
Escrito por Sergio M
Actualizado hace más de una semana

El ecosistema LoRaWAN sigue creciendo, y también lo hace la longitud de los decodificadores necesarios para transformar cargas útiles binarias o Base64 en cargas útiles JSON amigables. Copiar/pegar tales decodificadores puede resultar confuso por dos razones:

  • Algunos de ellos tienen cientos de líneas de código —y continúan creciendo a medida que se agregan más sensores y características a los dispositivos.

  • La mayoría —si no todos— los proveedores de LoRaWAN ofrecen sus decodificadores en NodeJS, lo que los hace incompatibles si estás desarrollando tus funciones en Python.

Debido a esto, creamos un endpoint público de DaaS (Decoder as a Service).

Requisitos

  • Una cuenta activa de Ubidots

  • Un código de NodeJS alojado públicamente

Tabla de Contenidos

1. Entendiendo los decodificadores proporcionados por el fabricante

La mayoría de los dispositivos IoT envían sus datos en formatos binarios o hexadecimales. Sin embargo, la mayoría de las aplicaciones en la nube de IoT esperan que los datos entrantes estén en una estructura JSON, con lecturas de sensores en formato decimal. Este proceso se conoce como "decodificación" de los datos del dispositivo.

Dado que la mayoría de los fabricantes de dispositivos LoRaWAN proporcionan funciones de decodificación, creamos un servicio de decodificación público para que puedas ejecutar dicho código a través de una simple solicitud de API, eliminando la necesidad de copiarlo y pegarlo en una consola de LoRaWAN, ejecutarlo en tu propio servidor, o incluso en un UbiFunction.

2. Cómo usar Ubidots DaaS

Para usar Ubidots DaaS, todo lo que necesitas hacer es hacer una solicitud POST a la siguiente URL:

Método HTTP

URL

POST

https://functions.ubidots.com/pub/decode/custom

Usando los siguientes encabezados HTTP:

Encabezado

Valor

Content-Type

application/json

X-Auth-Token

<tu-token-ubidots>

Con una carga útil JSON que contenga las siguientes claves:

Clave

Valor

Ejemplo

url

La URL pública que contiene el código que deseas ejecutar. Espera un texto sin formato.

https://raw.githubusercontent.com/Seeed-Solution/TTN-Payload-Decoder/master/SenseCAP_S2120_Weather_Station_Decoder.js

payload

Carga útil JSON, cuyas claves son los argumentos esperados por el decodificador

{    "fPort": 1,     "bytes":"SGVssIHdvckIQ="}

function

La función principal en el decodificador

decodeUplink

Nota: Al usar GitHub, asegúrate de establecer la URL en modo de texto sin formato.

Ejemplo

Considera que el decodificador que deseas usar está alojado en la siguiente URL:

https://raw.repository.com/myDecoder.js

Dicho decodificador contiene una función llamada decodeUplink, como:

function decodeUplink(args){    var bytes = args.bytes;    var port = args.fPort;    //Algún otro código que analiza los datos    return {"temperature" : xxx, "humidity" : yyy};}

Dado que espera tanto las claves fPort como bytes, necesitarías enviar exactamente el mismo JSON en la payload.

El cuerpo de una solicitud a este decodificador se vería así:

{    "url": "https://raw.repository.com/myDecoder.js",    "payload": {        "fPort": 1,         "bytes": "SGVsbG8sIHdvcmxkIQ="     },      "function": "decodeUplink"}

Después de hacer la solicitud, debería devolver el mismo objeto que en el decodificador, en este caso:

{"temperature" : xxx, "humidity" : yyy}

3. Implementación de DaaS en NodeJS

Lo siguiente es una implementación simple en NodeJS sobre cómo hacer tal solicitud. Puedes incorporar la función DaaS en tu código para llamar al decodificador que requieres.

const axios = require('axios')async function DaaS(decoderURL, functionName, payloadToDecode, ubidotsToken){    var headers = {"X-Auth-Token": ubidotsToken, "Content-Type": "application/json"};    var payload =     {        "url" : decoderURL,        "payload" : payloadToDecode,        "function" : functionName    }    var options =     {        "method" : 'post',        "url" : 'http://functions.ubidots.com/pub/decode/custom',        "data" : payload,        "json" : true,        "headers" : headers,    };    const  req = await axios.request(options);    return req.data.decoded; }

4. Implementación de DaaS en Python

Lo siguiente es una implementación simple en Python sobre cómo hacer tal solicitud. Puedes incorporar la función DaaS en tu código para llamar al decodificador que requieres.

def daas(decoder_url, entry_point, payload_to_decode, ubidots_token):    endpoint_url = 'http://functions.ubidots.com/pub/decode/custom'    headers = {"X-Auth-Token": ubidots_token, "Content-Type": "application/json"}    payload = {        "url": decoder_url,        "payload": payload_to_decode,        "function": entry_point    }    try:        response = requests.request('POST', endpoint_url, headers=headers, json=payload)        response.raise_for_status()        req = response.json()        return req['decoded']     except requests.exceptions.RequestException as e:        print(f"Ocurrió un error al hacer la solicitud: {e}")        return None

5. Decodificador de ejemplo

Hemos creado un decodificador ficticio y lo hemos alojado en esta URL: https://gist.github.com/RandomGenericUsername/ed777da3346928fcdbc8ff7bb8daf922

Dicho decodificador contiene el siguiente código y devuelve una carga útil JSON compatible con Ubidots:

function myDecoder(args){    var bytes = args.bytes;    var port = args.port;    var startFlag = bytes[0];    var temperature;    var humidity;    if(startFlag != 0xAA)    {        return {"Error" : "Bandera de inicio inválida"};    }    temperature = bytes[1] << 8 | bytes[2];    humidity = bytes[3] << 8 | bytes[4];    return {"temperature" : temperature, "humidity" : humidity};}

Ahora, considera un dispositivo que envía sus datos en una cadena hexadecimal con la siguiente estructura:

Byte

Descripción

Ejemplo

1

Bandera de inicio. Debe ser siempre 0xAA

AA

2-3

Datos de temperatura (big endian)

0062

4-5

Datos de humedad (big endian)

0032

1-5

carga útil completa

AA00620032

Veamos cómo se ve esta solicitud en NodeJS y Python.

Decodificador de ejemplo usando NodeJS

const axios = require('axios');const ubidotsToken = 'TU-TOKEN-UBIDOTS';const entryPoint = 'myDecoder';const decoderUrl = 'https://gist.githubusercontent.com/RandomGenericUsername/ed777da3346928fcdbc8ff7bb8daf922/raw/248d5e88b3341d16ffa9e1e22e52c2a06f030545/exampleDecoder.js';async function main(args){    var data = args.data;    var port = args.port;    var decoderExpectedObject = {"bytes" : Buffer.from(data, 'hex'), "port" : port};    var ubidotsPayload = await DaaS(decoderUrl, entryPoint, decoderExpectedObject, ubidotsToken);    console.log(ubidotsPayload);    //Si esto es una UbiFunction, necesitas hacer la solicitud al endpoint de dispositivos para enviar los datos a ese Dispositivo    //Si esto es un plugin, devuelve una carga útil compatible con Ubidots que contenga los datos del dispositivo}async function DaaS(decoderURL, functionName, payloadToDecode, ubidotsToken){    var headers = {"X-Auth-Token": ubidotsToken, "Content-Type": "application/json"};    var payload =     {        "url" : decoderURL,        "payload" : payloadToDecode,        "function" : functionName    }    var options =     {        "method" : 'post',        "url" : 'http://functions.ubidots.com/pub/decode/custom',        "data" : payload,        "json" : true,        "headers" : headers,    };    const  req = await axios.request(options);    return req.data.decoded; }

El siguiente GIF muestra el dispositivo simulado enviando datos y usando el decodificador alojado en Gist:

Decodificador de ejemplo usando Python

import requestsdecoder_url = 'https://gist.githubusercontent.com/RandomGenericUsername/ed777da3346928fcdbc8ff7bb8daf922/raw/d36303186c629d73dc3fd91c3d906e5697cd5b46/exampleDecoder.js'entry_point = 'myDecoder'ubidots_token = 'BBFF-ij2eOkYbTCrdrk6c7fdAxvpK7CTtVy'def main(args):    data = args['data'] # datos binarios entrantes    port = args['port']    decoder_expected_object = {"bytes": list(bytes.fromhex(data)), "port": port}    ubidots_payload =  daas(decoder_url, entry_point, decoder_expected_object, ubidots_token)    print(ubidots_payload)     #Si esto es una UbiFunction, necesitas hacer la solicitud al endpoint de dispositivos para enviar los datos a ese Dispositivo    #Si esto es un plugin, devuelve una carga útil compatible con Ubidots que contenga los datos del dispositivodef daas(decoder_url, entry_point, payload_to_decode, ubidots_token):    endpoint_url = 'http://functions.ubidots.com/pub/decode/custom'    headers = {"X-Auth-Token": ubidots_token, "Content-Type": "application/json"}    payload = {        "url": decoder_url,        "payload": payload_to_decode,        "function": entry_point    }    try:        response = requests.request('POST', endpoint_url, headers=headers, json=payload)        response.raise_for_status()        req = response.json()        return req['decoded']     except requests.exceptions.RequestException as e:        print(f"Ocurrió un error al hacer la solicitud: {e}")        return None

El siguiente GIF muestra el dispositivo simulado enviando datos y usando el decodificador alojado en Gist:

6. Solución de problemas

Ten en cuenta lo siguiente al usar Ubidots DaaS:

  1. Identifica la estructura de los argumentos entrantes en la función/plugin. Esto es para que puedas acceder a los datos entrantes. El formato de los argumentos entrantes suele ser impuesto por el LNS desde el cual el dispositivo está enviando datos.

    • Con respecto a esto, para ambos ejemplos de Python y NodeJS, que se muestran a continuación, asume que los datos binarios sin procesar llegan a la UbiFunction o Plugin dentro de la clave data en los argumentos de la función entrante.

  2. Identifica los argumentos que el decodificador del fabricante espera, para que puedas construir el JSON con esas mismas claves.

    • Con respecto a esto, para ambos ejemplos de Python y NodeJS, que se muestran a continuación, ten en cuenta que el decodificador ficticio espera las claves bytes y port en sus argumentos, por lo que necesitas construir el JSON en consecuencia para enviar al decodificador.

7. Comentarios, sugerencias y artículos relacionados

No dudes en publicar preguntas o sugerencias en nuestro portal de la comunidad, o contáctanos a través de support@ubidots.com.


Otros usuarios también encontraron útil...

¿Ha quedado contestada tu pregunta?