fbpx

En este tutorial te muestro cómo conectar rápidamente un dispositivo IoT a la plataforma Kaa.

Qué es la plataforma Kaa

Kaa es una plataforma IoT Open Source lista para usar. Incluye todo lo necesario para implementar una solución IoT, desde la gestión de dispositivos hasta la visualización, la gestión de usuarios y las analíticas.

Se puede utilizar en algunas de sus versiones cloud o en una solución on premise.

Además tiene una capa gratuita que permite registrar hasta 5 dispositivos.

Kaa está pensada para adaptarse a todos los mercados verticales de IoT, e incluso viene con algunos tableros predeterminados ( templates ) para aplicaciones de Smart Metering, Smart Building y Gestión de Flota.

La plataforma es agnóstica en cuanto a la tecnología utilizada en los nodos, ya que utiliza los protocolos HTTP o MQTT para realizar la conexiones con los dispositivos.

En cuanto a la gestión de dispositivos, implementa el concepto de digital twins. De esta manera, Kaa no solo mantiene una base de datos actualizada de los valores de las mediciones, sino de todas las características de los dispositivos.

Dentro de estas características pueden estar los números de serie, las direcciones físicas, las versiones del firmware y cualquier otro dato relevante que describa el dispositivo y su estado.

Una característica interesante es la conexión con distintos sistemas de manejo de datos y analíticas, como Open Distro for Elasticsearch.

Fuente: https://www.kaaproject.org/overview

Kaa además permite crear tableros de visualización de datos a partir de elementos gráficos configurables y adaptables del tipo drag and drop.

En cuanto a las notificaciones, dispone de varias opciones, entre ellas slack, mail, notificaciones push, SMS y otras. Además se pueden configurar la ejecución de acciones automáticas que actúen en los dispositivos remotos.

Otra característica interesante son las actualizaciones OTA ( over the air ), para gestionar las actualizaciones de los dispositivos de manera automática.

Finalmente, su capacidad multitenant permite tener distintos clientes en la misma plataforma y separar completamente los datos de cada uno de ellos.

Conectando una Raspberry Pi

En este tutorial voy a utilizar una computadora Raspberry Pi como dispositivo IoT y lo voy a conectar a la plataforma Kaa cloud.

Para esto, creo un script en Python con el siguiente código.

import argparse
import json
import logging
import os
import random
import signal
import string
import sys
import time
import paho.mqtt.client as mqtt

DEFAULT_KPC_HOST = os.getenv('DEFAULT_KPC_HOST', 'mqtt.cloud.kaaiot.com')
DEFAULT_KPC_PORT = os.getenv('DEFAULT_KPC_PORT', 1883)

EPMX_INSTANCE_NAME = os.getenv('EPMX_INSTANCE_NAME', 'epmx')
DCX_INSTANCE_NAME = os.getenv('DCX_INSTANCE_NAME', 'dcx')


def killhandle(signum, frame):
  logger.info("SIGTERM detected, shutting down")
  disconnectFromServer(client=client, host=host, port=port)
  sys.exit(0)


signal.signal(signal.SIGINT, killhandle)
signal.signal(signal.SIGTERM, killhandle)

# Configure logging
logger = logging.getLogger('mqtt-client')
logger.setLevel(logging.DEBUG)

hdl = logging.StreamHandler()
hdl.setLevel(logging.DEBUG)
hdl.setFormatter(logging.Formatter('%(levelname)s: %(message)s'))

logger.addHandler(hdl)

# Parse command line arguments and get device name
parser = argparse.ArgumentParser(description="MQTT client for demo application")
parser.add_argument("-d", "--deviceName", action="store", dest="deviceName", default="BME/BMP 280",
                    required=False, help="Name of connected device")
parser.add_argument("-a", "--appversion", action="store", dest="appversion", required=True,
                    help="Application version")
parser.add_argument("-t", "--token", action="store", dest="token", required=True,
                    help="Device token")
parser.add_argument("-s", "--host", action="store", dest="host", default=DEFAULT_KPC_HOST,
                    help="Server host to connect to")
parser.add_argument("-p", "--port", action="store", dest="port", default=DEFAULT_KPC_PORT,
                    help="Server port to connect to")
args = parser.parse_args()
appversion = args.appversion
token = args.token
client_id = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(6))
host = args.host
port = args.port
logger.info("Using EP token {0}, server at {1}:{2}".format(token, host, port))


def connectToServer(client, host, port):
  logger.info("Connecting to KPC instance at {0}:{1}...".format(host, port))
  client.connect(host, port, 60)
  logger.info("Successfully connected")


def disconnectFromServer(client, host, port):
  logger.info("Disconnecting from server at {0}:{1}.".format(host, port))
  time.sleep(4)  # wait
  client.loop_stop()  # stop the loop
  client.disconnect()
  logger.info("Successfully disconnected")


# METADATA section ------------------------------------
# Compose KP1 topic for metadata
metadata_request_id = random.randint(1, 99)
topic_metadata = "kp1/{application_version}/{service_instance}/{resource_path}".format(
  application_version=appversion,
  service_instance=EPMX_INSTANCE_NAME,
  resource_path="{token}/update/keys/{metadata_request_id}".format(token=token,
                                                                   metadata_request_id=metadata_request_id)
)
logger.debug("Composed metadata topic: {}".format(topic_metadata))


def composeMetadata(version):
  return json.dumps(
    {
      "model": "BME/BMP 280",
      "fwVersion": version,
      "customer": "Andrew",
      "latitude": 40.71427,
      "longitude": -74.00597,
    }
  )


# TELEMETRY section --------------------------------------
# Compose KP1 topic for data collection
data_request_id = random.randint(1, 99)
topic_data_collection = "kp1/{application_version}/{service_instance}/{resource_path}".format(
  application_version=appversion,
  service_instance=DCX_INSTANCE_NAME,
  resource_path="{token}/json/{data_request_id}".format(token=token, data_request_id=data_request_id)
)
logger.debug("Composed data collection topic: {}".format(topic_data_collection))


def composeDataSample():
  payload = [
    {
      "timestamp": int(round(time.time() * 1000)),
      "temperature": random.randint(18, 23),
      "humidity": random.randint(40, 60),
      "pressure": random.randint(980, 1000)
    }
  ]
  return json.dumps(payload)


def on_connect(client, userdata, flags, rc):
  if rc == 0:
    client.connected_flag = True  # set flag
    logger.info("Successfully connected to MQTT server")
  else:
    logger.info("Failed to connect to MQTT code. Returned code=", rc)


def on_message(client, userdata, message):
  logger.info("Message received: topic [{}]\nbody [{}]".format(message.topic, str(message.payload.decode("utf-8"))))


# Initiate server connection
client = mqtt.Client(client_id=client_id)
client.connected_flag = False  # create flag in class
client.on_connect = on_connect  # bind call back function

client.on_message = on_message
# Start the loop
client.loop_start()

connectToServer(client=client, host=host, port=int(port))

while not client.connected_flag:  # wait in loop
  logger.info("Waiting for connection with MQTT server")
  time.sleep(1)

# Send metadata once on the first connection
metadata = composeMetadata(version="v0.0.1")
client.publish(topic=topic_metadata, payload=metadata)
logger.info("Sent metadata: {0}\n".format(metadata))

# Send data sample in loop
while 1:
  payload = composeDataSample()
  result = client.publish(topic=topic_data_collection, payload=payload)

  if result.rc != 0:
    logger.info("Server connection lost, attempting to reconnect")
    connectToServer(client=client, host=host, port=port)
  else:
    logger.debug("{0}: Sent next data: {1}".format(token, payload))

  time.sleep(8)

Este script genera tres valores aleatorios (temperatura, humedad y presión). De esta manera no necesitamos conectar sensores reales para probar la plataforma. También podemos utilizar los valores de CPU, memoria, disco o temperatura de la propia Raspberry Pi. Para esto último podemos utilizar la librería psutil.

Para ejecutar el script es necesario pasarle dos parámetros como argumentos.

$ python client.py -a {application version} -t {token}

Configurando la plataforma

Para obtener los parámetros necesarios para ejecutar el script hay que seguir estos pasos.

Primero, dentro de una aplicación ya creada, agregar el dispositivo.

kaa iot agregad dispositivo
Agregando dispositivo en Kaa

Luego entramos al dispositivo y creamos un nuevo token.

kaa iot agregar token
Crear token

Esto nos abre una cuadro de diálogo donde podemos generar el nuevo token de manera automática (también podemos especificar uno nosotros).

kaa iot generar token
Generar token

Finalmente copiamos el token. Es importante copiar el token porque la plataforma no nos volverá a mostrar este dato por razones de seguridad.

kaa iot copiar token
Copiar token

Finalmente, ya tenemos el token generado y junto con la versión de la aplicación, podemos ejecutar el script.

kaa iot app version name token
Versión de aplicación y token

Probando la conexión

Finalmente ejecutamos el script con los parámetros y verificamos que se establezca la conexión con la plataforma.

$ python client.py -a aquí-va-tu-appVersion.name -t aquí-va-tu-token
Información recibida en Kaa

Conclusión

La plataforma Kaa es una opción muy interesante para cualquier proyecto IoT, debido a que incluye todas las capas de servicio de una plataforma IoT.

Además, se puede conectar fácilmente con sistemas de análisis de datos, lo que permite implementar analíticas avanzadas.

Por otro lado, admite la integración de cualquier tipo de dispositivo (hardware y software).

En este tutorial solo hemos conectado un dispositivo. En próximas entregas veremos cómo crear tableros y crear notificaciones.

Sin lugar a dudas te recomiendo que la pruebes. Puedes crear una cuenta gratuita y registrar hasta 5 dispositivos.

Finalmente, te invito a dejar tus dudas o comentarios más abajo.


0 comentarios

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

A %d blogueros les gusta esto: