Blog de Amazon Web Services (AWS)

AWS IoT Core

Por Jorge Alfaro, Arquitecto de Soluciones en Amazon Web Services México

 

AWS IoT Core es un servicio administrado en la nube que permite a los dispositivos conectados interactuar de manera fácil y segura con las aplicaciones en la nube y otros dispositivos. AWS IoT Core admite miles de millones de dispositivos y billones de mensajes, y es capaz de procesarlos y direccionarlos a puntos de enlace de AWS y a otros dispositivos de manera confiable y segura. Con AWS IoT Core, sus aplicaciones pueden realizar un seguimiento de todos los dispositivos y comunicarse con ellos en todo momento, incluso cuando no están conectados.

AWS IoT Core facilita la utilización de servicios de AWS, como AWS Lambda, Amazon Kinesis, Amazon S3, Amazon SageMaker, Amazon DynamoDB, Amazon CloudWatch, AWS CloudTrail, Amazon QuickSight y Alexa Voice Service para crear aplicaciones de IoT que recopilen, procesen, analicen y utilicen datos generados por dispositivos conectados sin tener que administrar ninguna infraestructura.

A continuación se crearán dispositivos para conectarlos con IoT Core y los mensajes que lleguen interactúen con otros servicios en AWS. En caso de que su interfaz en la consola de AWS no este en español, puede cambiar el idioma en la parte inferior izquierda del sitio.

Cómo crear un dispositivo en AWS IoT

Para este ejemplo, se utilizará AWS Cloud9, que es un entorno de desarrollo integrado (IDE) basado en la nube, desde ahí se emulará un dispositivo para realizar las conexiones a AWS IoT Core.  Esto es opcional pues también es posible realizar la instalación del CLI de AWS en una computadora con esta liga.

Como requerimientos para este ejemplo se necesitará acceso a la consola de AWS desde la cual se lanzarán los servicios de AWS Cloud9 y para crear los dispositivos en AWS IoT Core.

CREAR LA INSTANCIA EN CLOUD9

En Servicios escribir “Cloud9” :

En Cloud9, seleccionar “Create environment”,  luego ingresar un nombre para el ambiente, puede ser “DispositivosIoT” y seleccionar “Next Step”. En la siguiente pantalla se elige el tipo de máquina que se usará, para estos fines la opción más pequeña será suficiente. Se dejan las opciones como se muestra en esta imagen:

En la configuración de red, se puede seleccionar la VPC por default. Si se lanza la instancia de AWS Cloud9 desde una subred pública se podrá ingresar desde el navegador. En caso de que sea una subred privada, ya es posible ingresar usando AWS Systems Manager, en esta liga se explica el proceso.
Finalmente, en la última página hay que validar que todo esté correcto y seleccionar “Create environment”.

Esto tardará unos minutos y al terminar se tendrá un ambiente IDE. Ahora es necesario seleccionar el servicio de IoT Core:

Si nunca se ha usado IoT Core, en la consola se mostrara una página inicial. Solo dar clic en Introducción para continuar al menu principal. Ahora, seleccionar en el menú de la izquierda : Incorporar y luego Introducción. Seleccionar en el centro Incorporar un dispositivo y abajo Introducción.

En la siguiente página se mostrará una guía para configurar el primer dispositivo y poder descargar el SDK de acuerdo al lenguaje de programación que se desee. Dar click en Introducción.

Es necesario seleccionar la plataforma y el lenguaje del SDK, en este caso seleccionar LINUX/ OSX y Python y dar clic en Siguiente.

En la siguiente pantalla ingresar el nombre del dispositivo que se desea crear. Ingrese Dispositivo1 y clic en Paso Siguiente.

En el paso 2/3 se muestra el resumen de la información así como la política que se creará asociada al dispositivo y los certificados de seguridad que se usarán para conectarse a AWS IoT.

Se descarga el Kit de conexión y se guarda para usarse posteriormente. Se da clic en Paso siguiente, finalmente en la siguiente pantalla se pueden tomar nota de los pasos pero esos se explicarán más adelante. Y se da clic en el botón Listo

Como se observa en la última pantalla se han creado varios elementos:

Se da clic en Listo.

¿Qué elementos se han creado?

  • Primero se ha creado el objeto dentro de IoT en la sección Administración -> Objetos
  • Dentro de la sección Seguro->Certificados se ha agregado un certificado asociado al objeto creado.
  • Finalmente en la sección Seguro->Políticas también se creó una política que sí se revisa, se puede observar que permite recibir información de ciertos tópicos. Esta política se editará más adelante.

 

MODIFICAR LA POLÍTICA DE SEGURIDAD

En AWS IoT se requiere una política asociada a los certificados para autorizar acciones de los dispositivos, por mejores prácticas esta política debe ser lo más restrictiva posible y sólo indicar las acciones a las que tendrá acceso el dispositivo. Para efectos de pruebas es posible dejarla abierta y posteriormente cerrarla. Para editarla,  en el menu de la izquierda seleccionar Seguro->Políticas  y seleccionar el nombre de la política creada.  Una vez en la política dar clic en Editar el documento de política

E introducir el siguiente texto borrando toda la política anterior. Ésta política permite establecer una conexión desde el dispositivo con el Message Broker de AWS IoT Core, también permitirá que el dispositivo se suscriba y publique a algún tópico de MQTT y finalmente reciba algún mensaje.
Dar clic en Guardar una nueva versión cómo se indicó anteriormente, a modo de pruebas se hará muy abierta la política


{
"Version": "2012-10-17",
"Statement": [
    {
        "Action": [
            "iot:Publish",
            "iot:Subscribe",
            "iot:Connect",
            "iot:Receive"
        ],
        "Effect": "Allow",
        "Resource": [
            "*"
        ]
    }
    ]
}

¿Qué se ha hecho?

En este momento se ha creado un dispositivo  así como sus certificados que permiten la comunicación segura entre éste y AWS. También se ha creado una política de seguridad asociada al certificado que permite el uso de recursos dentro de AWS. Tanto el certificado como la política se han asociado al dispositivo creado. Estos 3 elementos son esenciales para lograr la comunicación entre los dispositivos en el borde y AWS IoT.

HACER LAS MODIFICACIONES EN EL DISPOSITIVO

Los siguientes pasos se realizarán en el ambiente de AWS Cloud9 que simulará el dispositivo que se conectará a AWS IoT Core. Estos pasos se pueden realizar en un equipo como laptop, Raspberry, etc. para lo cual es necesario tener instalado el SDK del lenguaje de programación que se usará. En este caso se usará Python y en los siguientes pasos se instalará.

Primero se creará una nueva carpeta. En el menú de la izquierda, dar botón derecho sobre el directorio y seleccionar New Folder y llamarlo Lab1

Seleccionar el nombre de la carpeta y dar clic en File para cargar los certificados descargados anteriormente de AWS IoT Core:

El archivo que se va a seleccionar en su computadora se debe llamar : connect_device_package.zip, una vez cargado debe verse dentro de la carpeta.

En la parte de abajo de la pantalla se encuentra la Terminal, como se ve en la imagen. Ahí se escriben los siguientes comandos.

Se requiere escribir la siguiente línea de código para instalar el SDK de IoT para Python:


sudo pip install AWSIoTPythonSDK
cd Lab1
unzip connect_device_package.zip
touch device1.py

Con el archivo device1.py creado, dar doble clic para abrirlo y copiar el siguiente código.

#!/usr/bin/python
# Lab 1 - Setting up.
# Make sure your host and region are correct.
import sys
import ssl
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient
import json
import time
import uuid
import random
import datetime
#Se puede cambiar el ID por el valor que se desee
ID = "1HGCP2F31BA126162"
#Setup our MQTT client and security certificates
#Make sure your certificate names match what you downloaded from AWS IoT
mqttc = AWSIoTMQTTClient(ID)
# Validar que se esta usando la region de us-east-1 para que el apuntador funcione
mqttc.configureEndpoint("COLOCAR PUNTO DE ENLACE AWS IOT AQUI",8883)
#
# IMPORTANTE
# Cambiar los nombre de XYZ.private.key y XYZ.private.key  por los nombres correctos de los certificados
mqttc.configureCredentials("./root-CA.crt","./XYZ.private.key","./XYZ.cert.pem")
#Function to encode a payload into JSON
def json_encode(string):
    return json.dumps(string)
mqttc.json_encode=json_encode
#Declaring trip_id variables
trip_id = str(uuid.uuid4())
# esto envia las variables al topico de IoT
def send():
    message = {
    "name": "speed",
    "value": 87,
    "id": ID,
    "trip_id": trip_id
    }
    # se codifica el archivo JSON
    message = mqttc.json_encode(message)
    mqttc.publish("tcu/vehicle/"+ID, message, 0)
    print ("Message Published" + message)
    #Connect to the gateway
mqttc.connect()
print ("Connected")
#Loop until terminated
while True:
    send()
    time.sleep(1)
mqttc.disconnect()
#To check and see if your message was published to the message broker
#go to the MQTT Client and subscribe to the iot topic and you should see
#your JSON Payload

Guardar el archivo y realizar las siguientes modificaciones: Se requiere obtener el certificado root, para lo cual en la parte de Terminal de Cloud9, ejecutar el siguiente comando en el mismo directorio que el archivo python:

curl https://www.amazontrust.com/repository/AmazonRootCA1.pem > root-CA.crt

Obtener el endpoint de AWS para que el dispositivo se conecte, esté se obtiene en la sección de Configuración (hasta abajo del menu de IoT Core) como se muestra en la imagen y copiar Punto de enlace.

Copiar este dato en el siguiente renglón:

mqttc.configureEndpoint("COLOCAR PUNTO DE ENLACE AWS IOT AQUI",8883)

Y modificar los nombres de los certificados por los que se generaron al crear el dispositivo en la línea 22

mqttc.configureCredentials("./root-CA.crt","./XYZ.private.key","./XYZ.cert.pem")

Guardar el archivo y en Terminal de AWS Cloud9 ejecutar:

python device1.py

Deben observarse los siguientes mensajes:

Connected
Message Published{"name": "speed", "value": 87, "id": "1HGCP2F31BA126162", "trip_id": "fabc3083-e34b-429f-8986-382e9754a435"}
Message Published{"name": "speed", "value": 87, "id": "1HGCP2F31BA126162", "trip_id": "fabc3083-e34b-429f-8986-382e9754a435"}
Message Published{"name": "speed", "value": 87, "id": "1HGCP2F31BA126162", "trip_id": "fabc3083-e34b-429f-8986-382e9754a435"}

Con lo que el dispositivo comenzará a enviar mensajes a AWS IoT Core, estos se pueden ver en IoT Core en la sección de Actuar  y luego Pruebas, y en la sección de Suscribir ingresar el símbolo: #  . La pantalla deberá quedar así:

Ya para finalizar es posible ver las conexiones hechas, los protocolos y la cantidad de mensajes recibidos en la sección de Monitorización en la parte superior derecha del menu.

Regresamos al IDE de AWS Cloud9 y detenemos la ejecución con Ctrl+C

Motor de Reglas

ALGUNOS CONCEPTOS BÁSICOS

Cuando los mensajes llegan a AWS IoT son procesados por un servicio llamado Message Broker, el cual conecta los mensajes que llegan y permite el envío de los mensajes a los dispositivos, todo esto mediante la suscripción o publicación a un tema o tópico.

El procesamiento de mensajes a través del agente permite la creación de reglas las cuales pueden iniciar acciones de acuerdo al contenido de los mensajes.

Estas acciones pueden ser interacciones con otros servicios de AWS como guardar los mensajes en un Amazon DynamoDB (una base de datos Llave – Valor), publicar los mensajes en una cola de Amazon SQS, invocar una función Lambda para realizar alguna tarea, grabar los datos a Amazon ElasticSearch, guardar los mensajes en AWS IoT Analytics o un repositorio de S3 como parte de un lago de datos, etc. Como se puede ver, el uso de las reglas ayuda a detonar acciones mas allá de solo guardar la información de los mensajes que llegan.

Para más detalles puede consultar la siguiente liga sobre las Reglas en AWS IoT

Paso previo

Antes de crear las reglas en AWS IoT Core es necesario entrar a Amazon DynamoDB para crear una tabla a la cual se enviarán los mensajes que llegan.

En la consola de AWS, se escribe Dynamo en la parte superior en Servicios. Una vez en Amazon DynamoDB, seleccionar Panel en el menú de la izquierda y posteriormente clic en Crear tabla.

El nombre de la tabla puede ser Tcu-speed, en Clave principal, escribir trip_id y seleccionar la opción Añadir clave de ordenación y escribir timestamp. Ambos tipos deben ser tipo Cadena a continuación se muestra los parámetros:

Seleccione Crear, después de unos minutos la tabla estará disponible.

En AWS IoT Core, en el menú de la izquierda, seleccionar Actuar y luego Reglas En la nueva pantalla seleccionar Crear una regla, e ingresar la siguiente información:

Nombre: tcuSpeedRule
Descripción: Regla para enviar datos a DynamoDb tabla TCU-SPEED

Instrucciones de consulta de regla:

SELECT * FROM 'tcu/vehicle/#'

Así deberá quedar la pantalla:


En la sección “Definir una o varias acciones” dar clic en Añadir acción y seleccionar la opción Dividir mensajes en varias columnas de una tabla de base de datos (DynamoDBv2) y dar clic en Configurar acción (Abajo en la pantalla).

En la siguiente pantalla seleccionar la tabla que previamente se creó en DynamoDB que debería tener el nombre Tcu-speed , dar clic en Crear un role, tecleamos: iot-dynamodb-rol y finalmente clic en Añadir acción .

Ahora, damos clic en Crear regla para terminar.

La regla que se ha creado está asociada al tópico “tcu/vehicle” por lo que cualquier mensaje que llegue con ese tópico será enviado a la tabla de DynamoDB. Al seleccionar la opción de “Dividir mensajes en varias columnas …” ayuda que toda la información que llegue en el documento JSON sea puesto en columnas. De lo contrario hubiera sido todo el documento en una sola columna

Regresando a AWS Cloud9 para ejecutar nuevamente el script:

En la linea 31, se cambiará el código para generar datos aleatorios en la velocidad y agregar la variable timestamp. El código original es:

def send():
    message = {
    "name": "speed",
    "value": 87,
    "id": ID,
    "trip_id": trip_id
    }

Pero ahora debe quedar de la siguiente forma:

def send():
    message = {
     "name": "speed",
     "value": random.randint(0,120),
     "vin": ID,
     "trip_id": trip_id,
     "timestamp": str(datetime.datetime.now())
     }

Se guarda el archivo y ahora se ejecuta el siguiente código en la ventana de Terminal.

python device1.py

Los mensajes llegarán directamente a la tabla de Amazon DynamoDB . Para poder verlos en en el tab Elementos se pueden ver los mensajes que llegan dentro del servicio de Amazon DynamoDB.

En AWS Cloud9 se detiene el script con Ctrl+C.

Ejecutar una acción o disparar una alarma

Ya se tiene la información guardada en Amazon DynamoDB, pero ¿qué sucede si se desea ejecutar alguna acción por si una métrica sobrepasa un umbral determinado? Las reglas pueden ejecutar varias acciones al mismo tiempo, lo que a continuación se hará es agregar una nueva regla para ejecutar el servicio de Amazon Simple Notification Service (Amazon SNS). Este servicio permite agregar muchas acciones, que ayudan a la integración de la solución de IoT con otros elementos en AWS.

A continuación se creará un Tema en SNS, se enrutarán los mensajes de AWS IoT Core a SNS y se usara Amazon Simple Queue Service para ver los mensajes con fallas.

CREAR UN TEMA EN SNS

En la consola de AWS en Servicios, escribir “SNS“.

En la pantalla seleccionar el menú de la izquierda y dar clic en Temas y luego clic en el botón naranja Crear un tema

Ingresar los siguientes datos:

  • Nombre : SNSAlertaVelocidad
  • Nombre para visualización: AlertaVelocidad

Como se muestra en la siguiente pantalla y dar clic en Crear un tema.

Una vez creado el tema, en la siguiente pantalla dar clic en Crear una suscripción.

Para crear una suscripción se requiere ingresar los siguientes datos:

  • Protocolo: SMS
  • Punto de enlace : (Ingrese su número celular a 12 dígitos con signo + al inicio)

De clic en Crear una suscripción.

 

CREAR UNA COLA EN SQS

Ahora se creara una cola en SQS. En la consola de AWS, en Servicios teclear “SQS” e ingresar al servicio. Dar clic en “Crear una Cola

El tipo de cola será Estándar. Se ingresa el nombre de la cola : ColaAlertasVelocidad Todos los otros valores se dejan sin cambio. Dar clic en Crear una cola.

Una vez creada la cola se selecciona el botón naranja Suscribirse al tema de Amazon SNS.

En la siguiente pantalla seleccionar el ARN creado en SNS. Si tiene varios, debe encontrarlo por el nombre que le dio. Y posteriormente clic en Guardar.

En este punto, cualquier mensaje que llegue al Tema de SNS sera colocado en la cola de SQS.

CREAR UNA NUEVA REGLA DE IOT CORE

Ahora se agregará una nueva regla en AWS IoT Core que ejecutará una acción para enviar los datos al tema de SNS.

Ingresar a AWS IoT Core, en la consola de AWS. En la pantalla principal de AWS IoT, en el menú de la izquierda seleccionar Actuar y luego Reglas:

Si no hay reglas, dar clic en Crear regla al centro de la pantalla, de lo contrario seleccionar el botón azul arriba a la derecha Crear .

En la siguiente pantalla ingresar los siguientes valores: Nombre : ReglaAlertaVelocidad Instrucción de consulta de regla:

SELECT "Alerta: velocidad mayor a 80" as msg from "tcu/vehicle/#" WHERE value > 80

La pantalla se vera de esta forma:

Posteriormente en la sección Definir o una varias acciones dar clic en Añadir acción, en la siguiente pantalla seleccionar Enviar un mensaje como notificación push SNS y bajar la pantalla hasta Configurar acción

En la siguiente pantalla, seleccionar el SNS que se creo previamente, y el tipo de formato debe ser RAW. Dar clic en Crear un rol (en la ventana emergente, escribir Iot_SNS_Rol   y dar clic en Crear rol).  Verificar que la política se adjuntó en la siguiente pantalla  y dar clic Añadir acción.

Dar clic en Crear regla en la parte baja de la pantalla.

Enviar mensajes para verificar mensajes

Nuevamente, en la interfaz de AWS Cloud9, será necesario volver a ejecutar el script:

python device1.py

Tan pronto se tenga un valor mayor a 80 en Speed, se disparará la regla:

Para ver los mensajes en la cola de SQS regresar al servicio y dar clic en el botón de arriba a la izquierda para listar las colas:

En la lista de colas, marcar la línea : ColaAlertasVelocidad  y posteriormente Enviar y recibir mensajes.

En la siguiente pantalla, en medio dar clic en el botón : Sondeo de mensajes para comenzar a ver los que están en la fila.  También llegarán estas alertas via mensaje de SMS al celular suscrito.

Por último, detener el script en AWS Cloud9 para dejar de generar mensajes.

Servicio Device Shadow

El servicio Device Shadow de AWS IoT agrega un elemento llamado Shadow o Sombra a objetos de AWS IoT. Los Shadows pueden hacer que el estado de un dispositivo esté disponible para las aplicaciones y otros servicios, independientemente de que el dispositivo esté conectado a AWS IoT o no. Los objetos de AWS IoT pueden tener varios Shadows con nombre para que su solución de IoT tenga más opciones para conectar los dispositivos a otras aplicaciones y servicios.

Cada Shadow tiene un Tema MQTT y una URL HTTP que admite las acciones get , update y delete . Los Shadows utilizan documentos JSON para almacenar y recuperar datos.  Un documento de Shadows contiene una propiedad de estado que describe estos aspectos del estado del dispositivo:

  • desired :  Las aplicaciones especifican los estados deseados de las propiedades del dispositivo actualizándolo.
  • reported : Los dispositivos notifican su estado actual.
  • delta : AWS IoT notifica las diferencias entre el estado desired y reported con este objeto.

Es importante considerar que los estados de los Shadows son dinámicos y los puede modificar los dispositivos, las aplicaciones y otros servicios en la nube con los permisos adecuados. Por lo que se recomiendan estas mejores prácticas:

  • Los dispositivos deben escribir solo en la propiedad reported del estado del Shadow.
  • Las aplicaciones y otros servicios en la nube deben escribir solo en la propiedad desired al comunicar solicitudes de cambio de estado al dispositivo a través del Shadow.

A continuación se creará otro archivo para escribir en el directorio  Lab1  con el siguiente comando en la sección Terminal de Cloud9

touch fabrica.py

Copiar el siguiente código:

import sys
import ssl
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTShadowClient, AWSIoTMQTTClient
import json
import time
from random import randint
# IMPORTANTE: CAMBIAR AQUI el nombre del device que se dio de Alta en AWS IoT Core
ThingName = "Dispositivo1"
clientId = "Reader"
# El motor esta apagado
MOTOR_STATUS = "OFF"
mqttShadowClient = AWSIoTMQTTShadowClient(clientId)
# Cambiar estos parametros de Endpoint y certificados:
mqttShadowClient.configureEndpoint("COLOCAR EL ENDPOINT CORRECTO",8883)
mqttShadowClient.configureCredentials("./root-CA.crt","./Dispositivo1.private.key","./Dispositivo1.cert.pem")
shadowClient=mqttShadowClient.createShadowHandlerWithName(ThingName,True)
mqttClient = mqttShadowClient.getMQTTConnection()
def updateDeviceShadow():
    global shadowClient
    print ("Modificar status de Sombra")
    shadowMessage = {"state":{"reported":{"MOTOR": MOTOR_STATUS}}}
    shadowMessage = json.dumps(shadowMessage)
    shadowClient.shadowUpdate(shadowMessage, validar_actualizacion, 5)
# Validar si la actualizacion se realizo
def validar_actualizacion(payload, responseStatus, token):
    # payload is a JSON string ready to be parsed using json.loads(...)
    # in both Py2.x and Py3.x
    if responseStatus == "timeout":
        print("Actualizacion solicitada " + token + " time out!")
    if responseStatus == "accepted":
        print ("Status del motor actualizado exitosamente!")
    if responseStatus == "rejected":
        print("Solicitud de actualizacion " + token + " denegada!")
# Custom Shadow callback
def customShadowCallback_Delta(payload, responseStatus, token):
    global MOTOR_STATUS
    # Los topicos son archivos JSON y se analizan con json.loads(...)
    payloadDict = json.loads(payload)
    print ("Sombra de Dispositivo ... OK")
    # Validar los datos que se mandan
    if "MOTOR" not in payloadDict["state"]:
        print ("Error: Invalid request, device cannot perform action.")
        return
    #  Obtener Status del motor, ejecutar accion, y luego actualizar sombra del dispositivo
    status = payloadDict["state"]["MOTOR"]
    if status == "ON":
        print ("Llega solicitud para encender motor.")
        MOTOR_STATUS = status
        updateDeviceShadow()
    elif status == "OFF":
        print ("Deteniendo motor.")
        MOTOR_STATUS = status
        updateDeviceShadow()
    else:
        print ("Parametros invalidos, enviar 'ON' u 'OFF'")
#funcion para codificar los textos en Json
def json_encode(string):
        return json.dumps(string)
mqttClient.json_encode=json_encode
# Se mandan valores aleatorios de temperatura
def send():
    global MOTOR_STATUS
    temp = randint(0, 100)
    message ={
        'temp': temp,
        'unit' : 'C'
    }
    message = mqttClient.json_encode(message)
    mqttClient.publish("data/temperature", message, 0)
    print ("Mensaje de temperatura PUBLICADO")
    # Unicamente se mandan valores de vibracion con el motor prendido
    if MOTOR_STATUS == "ON":
        vibration = randint(-500, 500)
        message = {
            'vibration' : vibration
        }
        message = mqttClient.json_encode(message)
        mqttClient.publish("data/vibration", message, 0)
        print ("Motor prendido. Enviando datos de vibracion")
#Conectar al gateway
mqttShadowClient.connect()
print ("Conectado")
#Set the current motor status in the device shadow
updateDeviceShadow()
# Ver por cambios en Deltas
shadowClient.shadowRegisterDeltaCallback(customShadowCallback_Delta)
#Ciclo
while True:
    send()
    time.sleep(5)
mqttShadowClient.disconnect()

Nuevamente es importante cambiar el Endpoint y los nombres de los certificados.

Se requiere crear otro archivo para enviar comandos y prender o apagar el motor :

touch comandos.py

Abrir el archivo y copiar el siguiente código.


#!/usr/bin/python
import sys
import ssl
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTShadowClient
import json
import time
import argparse

# Parametros de entrada
parser = argparse.ArgumentParser()
parser.add_argument("-a", "--accion", action="store", required=True, dest="status", help="Prende o apaga el Motor : ON / OFF")

args = parser.parse_args()
status = args.status

# Colocar el nombre del device correcto
ThingName = "Dispositivo1"


clientId = "Writter"
mqttc = AWSIoTMQTTShadowClient(clientId)


# Validar que se esta usando la region de us-east-1 para que el apuntador funcione
mqttc.configureEndpoint("COLOCAR EL ENDPOINT CORRECTO",8883)
#
# IMPORTANTE
# Cambiar los nombre de XYZ.private.key y XYZ.private.key  por los nombres correctos de los certificados
mqttc.configureCredentials("./root-CA.crt","./XYZ.pem.key","./XYZ.pem.crt")
mqttc.connect()

MOTOR_STATUS = status

shadowClient=mqttc.createShadowHandlerWithName(ThingName,True)
shadowMessage = {"state":{"desired":{"MOTOR":MOTOR_STATUS}}}
shadowMessage = json.dumps(shadowMessage)

# Enviando la primera actualizacion

print ("Conectado")
shadowClient.shadowUpdate(shadowMessage,None, 5)
print ("Actualizacion de Sombra enviado")
time.sleep(5)
mqttc.disconnect()

Se requiere cambiar el nombre del dispositivo, colocar el EndPoint correcto y los certificados.

Este archivo será ejecutado colocando el parámetro de ON u OFF.

Este archivo representa un centro de comando donde de forma remota se puede iniciar o detener un motor. Dado que en ocasiones se puede perder comunicación con la fábrica, el último estado deseado permanece en AWS IoT Core para que tan pronto se tenga conectividad se actualice el estado.

Para que se tengan ambos archivos en ejecución, en AWS Cloud9 se puede abrir otra ventana de Terminal. En el menú superior clic en Window -> New Terminal y así se tendrá la pantalla de Terminal abajo y otra arriba.

Ejecutar el siguiente archivo en la pantalla de Terminal superior

python fabrica.py

En la primera pantalla se tendrá ejecutando el motor.  Para ver los mensajes que llegan a AWS, ir a Aws IoT Core, luego en Administración -> Objetos dar clic en el nombre del Dispositivo. En la siguiente pantalla clic en Sombras y luego en los 3 puntitos a la derecha, se verá una pantalla similar a la siguiente:

Como se puede ver ya se creo un estado REPORTED sobre lo que envío el dispositivo a la sombra en AWS.

De regreso en AWS IoT Core, dar clic en Prueba, abajo en el menú a la izquierda. Y en la siguiente pantalla, clic en Suscribirse a un tema e ingresar el siguiente texto en Tema de suscripción

$aws/things/Dispositivo1/shadow/update/documents

Si el nombre del dispositivo en AWS IoT Core NO es Dispositivo1  hay que editar esa parte, ahi se indicará el nombre del dispositivo. Con este tópico se verán los documentos JSON que llegan respecto al Shadow.

Ahora, de regreso en AWS Cloud9, en la pantalla de Terminal inferior ejecutamos:

 python comandos.py -a ON

Se verán los siguientes mensajes en la pantalla de Terminal donde se ejecutó el script fabrica.py:

El mensaje que se mostrará en el Shadow del dispositivo que llega al tópico suscrito sera como este:

Como se puede ver, hay una diferencia entre el estado desired y el reported, por lo tanto hace el cambio modificando el estado de la sombra.
Con este ejemplo se puede ver el uso de Device Shadow en AWS IoT Core. Es importante señalar que también es posible usar las sombras como tópicos de MQTT y por medio de REST APIs.
En el caso de los tópicos de MQTT AWS ha reservado la palabra $aws para ese fin. En la siguiente liga se listan los tópicos y su uso: Tópicos de Sombras en AWS IoT
Las aplicaciones se pueden comunicar con AWS IoT Core por medio de API Rest, para lo cual la estructura es la siguiente:

https://endpoint/things/thingName/shadow

Donde, endpoint se ha usado anteriormente para conectarse a AWS IoT Core en el código de python. Y thingName es el nombre del dispositivo en AWS IoT Core.
Para más detalle puede consultar la siguiente liga API REST de Sombras en AWS IoT

Resumen

En este documento se ha visto cómo es posible establecer la comunicación con dispositivos con AWS IoT Core estableciendo una comunicación segura y definiendo políticas de acuerdo a lo que requiera hacer. También se crearon reglas para direccionar los mensajes que llegan y realizar acciones dentro de AWS con varios servicios.
Finalmente, se explicó el uso de Device Shadow y cómo es que estas pueden ayudar a las aplicaciones a interactuar con los dispositivos que posiblemente sufran desconexiones de Internet y de esta forma evitar perder comandos que se les envían.

 


Sobre el autor

Jorge Alfaro, Arquitecto de Soluciones en Amazon Web Services México.
Cuenta con mas de 25 años de experiencia en la industria, ayudando a grandes corporativos en diseñar y mover sus cargas de trabajo a la nube de AWS, su área de especialidad es IoT