O blog da AWS

Explorando as Possibilidades do AWS IoT Core

 

Por Breno Silva, Arquiteto de Soluções na AWS
Por Pedro Assumpção, Consultor de Aplicações na AWS

 

O AWS IoT Core é um serviço gerenciado na nuvem, que permite aos dispositivos conectados interagirem de maneira fácil e segura com outros dispositivos e aplicações em nuvem. O AWS IoT Core oferece suporte a bilhões de dispositivos e trilhões de mensagens, e é capaz de processá-las e roteá-las para endpoints da AWS e outros dispositivos de forma confiável e segura. Com o AWS IoT Core, seus aplicativos podem rastrear e se comunicar com todos os dispositivos em todos os momentos, mesmo quando não estão conectados.

O AWS IoT Core facilita a integração com serviços da AWS, como AWS Lambda, Amazon Kinesis, Amazon S3, Amazon SageMaker, Amazon DynamoDB, Amazon CloudWatch, AWS CloudTrail, Amazon QuickSight e Alexa Voice Service para criar aplicativos de IoT que coletam, processam, analisam e usam dados gerados por dispositivos conectados sem precisar gerenciar nenhuma infraestrutura.

Neste blog, mostraremos como criar dispositivos para conectar ao AWS IoT Core, e faremos a integração das mensagens que chegarem com outros serviços da AWS. Se sua interface no console da AWS não estiver em português, você poderá alterar o idioma no canto inferior esquerdo do site.

 

 

Pré-requisitos

Para este passo a passo, você deve ter os seguintes pré-requisitos:

  • Uma conta na AWS
  • Acesso aos serviços da família de IoT na AWS
  • Acesso ao AWS Cloud9
  • Conhecimentos gerais de nuvem

 

Como criar um dispositivo no AWS IoT

Para este exemplo, será usado o AWS Cloud9, que é um ambiente de desenvolvimento integrado (IDE) baseado em nuvem, a partir daí um dispositivo será emulado para fazer conexões com o AWS IoT Core. Isso é opcional porque também é possível instalar a AWS CLI em um computador com este link.

Como requisitos para este exemplo, você precisará ter acesso ao console da AWS, a partir do qual os recursos do AWS Cloud9 e os dispositivos do AWS IoT Core serão criados.

Criando A Instância No Cloud9

Em Serviços, digite “Cloud9”:

 

 

No Cloud9, selecione Create Environment, insira um nome para o ambiente, ele pode ser “DispositivoIoT” e selecione Next Step. Na próxima tela, você escolhe o tipo de máquina a ser usada, para esses propósitos a menor opção será suficiente. As opções são deixadas como mostrado nesta imagem:

 

 

Na configuração de rede, você pode selecionar a VPC padrão. Se a instância do AWS Cloud9 for executada a partir de uma sub-rede pública, ela poderá ser acessada a partir do navegador. Caso seja uma sub-rede privada, agora é possível fazer login usando o AWS Systems Manager, em que esse link explica o processo.

Finalmente, na última página você precisa validar que tudo está correto e selecionar Create Environment.

Isso levará alguns minutos e, no final, você terá um ambiente de desenvolvimento. Agora você precisa selecionar o serviço AWS IoT Core:

 

 

Se o AWS IoT Core nunca tiver sido usado antes, uma página inicial pode ser exibida no console. Selecione no menu à esquerda: Incluir e depois Conceitos básicos. Selecione Integre um dispositivo no centro e abaixo de Primeiros passos.

A próxima página mostrará um guia para configurar o primeiro dispositivo e baixar o SDK, de acordo com a linguagem de programação desejada. Clique em Conceitos Básicos.

 

 

Você precisa selecionar a plataforma e o idioma do SDK, neste caso, selecionar LINUX/ OSX e Python e clicar em Avançar.

Na próxima tela, insira o nome do dispositivo que você deseja criar. Digite Device1 e clique em Próxima etapa.

A Etapa 2/3 exibe o resumo das informações, bem como a política que será criada associada ao dispositivo e os certificados de segurança que serão usados para se conectar ao AWS IoT.

 

 

O Kit de Conexão é baixado e salvo para uso posterior. Clique em Próxima Etapa, finalmente, na próxima tela, você pode anotar as etapas, mas elas serão explicadas mais tarde. E clique no botão Concluído

Como visto na última tela, vários itens foram criados:

 

 

Clique em Concluído.

Uma coisa (de Internet das Coisas) é a representação lógica do seu dispositivo dentro do AWS IoT Core. Ela é composta de três elementos:

  • Registro: O Registry estabelece uma identidade para dispositivos e rastreia metadados, como os atributos e recursos dos dispositivos. O Registry atribui uma identidade exclusiva para cada dispositivo, a qual tem um formato padrão, independentemente do tipo de dispositivo ou de como ele estabelece conexões. Ele também é compatível com metadados que descrevem os recursos de um dispositivo, por exemplo, se um sensor reporta a temperatura, e se os dados são em Fahrenheit ou Celsius.
  • Certificado: O AWS IoT Core disponibiliza autenticação e criptografia mútuas em todos os pontos de conexão, de modo que os dados nunca sejam trocados entre os dispositivos e o AWS IoT Core sem uma identidade comprovada. O AWS IoT Core oferece suporte ao método de autenticação da AWS (denominado “SigV4”), à autenticação baseada em certificado X.509 e à autenticação baseada em tokens criados pelo cliente (por meio de autorizadores personalizados).
  • Política de acesso: Você pode mapear sua escolha de políticas para cada certificado, de modo que você possa autorizar os dispositivos ou aplicativos para ter acesso, ou mudar de ideia e revogar totalmente o acesso sem nunca sequer mexer no dispositivo. Seus certificados podem ser associados com as políticas de IoT relevantes configuradas usando o AWS IoT Core. Isso permite, por exemplo, que você revogue instantaneamente o acesso de um dispositivo individual, caso você decida fazer isso.

Você pode ver detalhes na seção Gerenciar -> Coisas.

  • Dentro da seção Proteger -> Certificados, um certificado associado ao objeto criado foi adicionado.
  • Por fim, na secção Proteger -> Políticas, também foi criada uma política que permite receber mensagens em certos tópicos. Esta política será editada no tópico a seguir.

 

Modificar A Política De Segurança

No AWS IoT, uma política associada a certificados é necessária para autorizar ações do dispositivo. Para as melhores práticas, essa política deve ser o mais restritiva possível e indicar apenas as ações às quais o dispositivo terá acesso. Para fins de teste, é possível deixá-lo aberto e depois fechá-lo. Para editá-lo, no menu esquerdo, selecione Proteger -> Políticas e selecione o nome da política criada. Uma vez na política, clique em Editar o documento de política

 

 

E insira o texto a seguir excluindo toda a política anterior. Essa política permite que você estabeleça uma conexão do dispositivo com o AWS IoT Core Message Broker, também permitirá que o dispositivo se subscreva e publique em algum tópico MQTT e, finalmente, receba uma mensagem. Clique em Salvar uma nova versão conforme indicado acima.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iot:Connect"
      ],
      "Resource": [
        "arn:aws:iot:us-east-1:881464459139:client/${iot:Connection.Thing.ThingName}"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "iot:Publish",
        "iot:Subscribe",
        "iot:Receive"
      ],
      "Resource": [
        "arn:aws:iot:us-east-1:881464459139:topic/tcu/vehicle/${iot:Connection.Thing.ThingName}*",
        "arn:aws:iot:us-east-1:881464459139:topic/data/*",
        "arn:aws:iot:us-east-1:881464459139:topic/$aws/things/${iot:Connection.Thing.ThingName}/shadow/*",
        "arn:aws:iot:us-east-1:881464459139:topicfilter/$aws/things/${iot:Connection.Thing.ThingName}/shadow/*"
      ]
    }
  ]
}

O que foi feito?

No momento, um dispositivo foi criado, bem como seus certificados que permitem a comunicação segura entre ele e a AWS. Uma política de segurança também foi criada e associada ao certificado que permite o uso de recursos na AWS. O certificado e a política foram associados ao dispositivo criado. Esses três elementos são essenciais para alcançar a comunicação entre dispositivos na borda e o AWS IoT.

Faça Modificações No Dispositivo

As etapas a seguir serão executadas no ambiente do AWS Cloud9 que simulará o dispositivo que se conectará ao AWS IoT Core. Essas etapas podem ser executadas em um computador como laptop, Raspberry, etc. Para o qual é necessário ter o SDK da linguagem de programação a ser usada instalado. Nesse caso, o Python será usado e, nas etapas a seguir, ele será instalado.

Uma nova pasta será criada primeiro. No menu à esquerda, clique com o botão direito do mouse no diretório e selecione New Folder e chame-a de Lab1. Selecione o nome da pasta com o botão esquerdo do mouse, clique em File, e em seguida clique em Upload Local Files para carregar certificados baixados anteriormente do AWS IoT Core:

 

 

O arquivo a ser selecionado no seu computador deve se chamar: connect_device_package.zip, uma vez carregado, ele deve ser visualizado dentro da pasta.

Na parte inferior da tela está o Terminal, como pode ser visto na imagem. Os comandos a seguir estão escritos. Selecione o nome da pasta e clique em Arquivo para carregar certificados baixados anteriormente do AWS IoT Core:

 

 

Você precisa escrever a seguinte linha de código para instalar o IoT SDK para Python:

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

Com o arquivo device1.py criado, iremos coletar algumas informações necessárias para a conexão com o AWS IoT Core: o endpoint da sua conta para o serviço e o certificado Root da AWS.

No Terminal do Cloud9, execute o seguinte comando no mesmo diretório que o arquivo Python:

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

Para obter o endpoint para conectar seu dispositivo, clique na seção Configuração (na parte inferior do menu IoT Core), conforme mostrado na imagem, e copie o Endpoint.

 

 

Copie o endpoint para um arquivo de texto, teremos que substituí-lo no código que simula o dispositivo. O trecho de código será como este, onde está indicado onde deverá ser feita a modificação:

mqttc.configureEndpoint("COLOCAR ENDPOINT DO AWS IOT AQUI",8883)
mqttc.configureCredentials("./root-CA.crt","./Device1.private.key","./Device1.cert.pem")

Retorne ao seu ambiente do Cloud9. No menu de navegação à esquerda, clique duas vezes no arquivo criado (device1.py) para abri-lo e copie o código a seguir.

#!/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
# Você pode alterar o ID para o valor desejado
ID = "Device1"
#Setup our MQTT client and security certificates
#Make sure your certificate names match what you downloaded from AWS IoT
mqttc = AWSIoTMQTTClient(ID)
mqttc.configureEndpoint("COLOCAR ENDPOINT DO AWS IOT AQUI",8883)
#
# IMPORTANTE
# Renomeie para os nomes de certificado corretos
mqttc.configureCredentials("./root-CA.crt","./Device1.private.key","./Device1.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())
# isso envia as variáveis para o tópico IoT
def send():
message = {
"name": "speed",
"value": random.randint(0,120),
"vin": ID,
"trip_id": trip_id,
"timestamp": str(datetime.datetime.now())
}

# o arquivo JSON é codificado
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

Salve o arquivo e faça as seguintes substituições:

Na linha 17, preencha com o endpoint do AWS IoT Core, copiado na etapa anterior. O resultado deve ficar semelhante a este:

mqttc.configureEndpoint("xxxxxxxxxx-ats.iot.us-east-1.amazonaws.com",8883)

Na linha 21, verifique se os diretórios do Root CA, chave privada e certificado do dispositivo estão de acordo com os arquivos que você salvou. Estas credenciais serão utilizadas para a autenticação mútua com o AWS IoT Core.

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

Salve o arquivo e, no Terminal do AWS Cloud9, execute:

python device1.py

As seguintes mensagens devem ser observadas:

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"}

Com este arquivo o dispositivo começará a enviar mensagens para o AWS IoT Core. Para as visualizar, vá para a seção Testar no AWS IoT Core e, em seguida, na seção Cliente de teste MQTT, insira o caractere: #. Este caractere é chamado de wildcard, do qual o utilizamos para incluir todas as mensagens em tópicos naquele nível de hierarquia e abaixo. Por exemplo, se você colocar um filtro para assinar mensagens como “data/#”, serão recebidas mensagens dos tópicos “data/temperature”, “data/pressure/floor1”, e assim por diante, mas não serão recebidas mensagens de “vehicle/location”.

Após inseri-lo, Clique em Inscrever-se. A tela deve ficar assim:

 

 

Por fim, é possível visualizar as conexões feitas, os protocolos e o número de mensagens recebidas na seção Monitoramento no canto superior direito do menu.

 

 

Volte ao AWS Cloud9 IDE, clique no terminal e execute Ctrl+C (ou Command+C) para parar a execução do script.

Mecanismo de regras

Alguns Princípios Básicos

As mensagens publicadas no AWS IoT Core são intermediadas por um broker de mensagens, seguindo o protocolo MQTT. Outros dispositivos e aplicações podem subscrever a estes tópicos para processar as mensagens e tomar decisões com base em dados.

O mecanismo de regras permite o processamento contínuo de dados recebidos no broker do AWS IoT Core. Você pode configurar regras no mecanismo de regras em uma sintaxe tipo SQL intuitiva para filtrar e transformar automaticamente os dados recebidos. Você pode configurar ainda mais as regras para rotear dados do AWS IoT Core para vários outros serviços da AWS, seus próprios serviços ou serviços de terceiros. Essas ações podem ser interações com outros serviços da AWS, como salvar mensagens em um Amazon DynamoDB (um banco de dados de chave-valor), publicar mensagens em uma fila do Amazon SQS, invocar uma função do Lambda para executar alguma tarefa, gravar dados no Amazon OpenSearch, salvar mensagens no AWS IoT Analytics ou um repositório como parte de um data lake, etc. Para obter mais detalhes, consulte o seguinte link sobre Regras no AWS IoT.

Preparação

Antes de criar regras no AWS IoT Core, você precisa fazer login no Amazon DynamoDB para criar uma tabela para a qual as mensagens recebidas serão enviadas.

No console da AWS, digite DynamoDB na parte superior em Serviços. Uma vez no Amazon DynamoDB, selecione Tabelas no menu à esquerda e clique em Criar Tabela.

O nome da tabela pode ser Tcu-Speed, em Chave de partição (Partition key), digite trip_id e digite timestamp para o nome da Chave de classificação (Sort key). Ambos os tipos devem ser do tipo String abaixo são os parâmetros:

 

 

Selecione Criar tabela, depois de alguns minutos a tabela estará disponível.

De volta ao console do AWS IoT Core, no menu à esquerda, selecione Agir e, em seguida, Regras.

Para definir uma instrução de regra, as sentenças utilizadas para gera-las são construídas conforme uma sintaxe SQL para filtrar e tratar as mensagens MQTT recebidas ou enviadas pelo tópico da qual está sendo aplicada.

Sendo assim, na nova tela, selecione Criar e insira as seguintes informações:

Nome: tcuSpeedRule

Descrição: Regra para enviar dados para a tabela TCU-SPEED do DynamoDB

Instruções de consulta da regra:

SELECT * FROM 'tcu/vehicle/#'

É assim que a tela deve ficar:

 

 

Na seção “Definir uma ou mais ações”, clique em Adicionar ação e selecione a opção Dividir mensagens em várias colunas de uma tabela de banco de dados (DynamoDBv2) e clique em Configurar ação (Abaixo na tela).

Na tela seguinte, selecione a tabela que foi criada anteriormente no DynamoDB que deve ter o nome Tcu-speed, clique em Criar função, digite: iot-dynamodb-role e, finalmente, clique em Adicionar Ação.

 

 

Agora, clicamos em Criar regra para finalizar.

A regra que foi criada está associada ao tópico “tcu/vehicle” para que qualquer mensagem que chegue com esse tópico seja enviada para a tabela do DynamoDB. Selecionar a opção “Dividir mensagens em várias colunas…” ajuda a que todas as informações que chegam ao documento JSON sejam colocadas em colunas. Caso contrário, o documento inteiro seria armazenado em uma única coluna.

Retornando ao ambiente do AWS Cloud9, vamos alterar uma parte do código para incluir valores aleatórios nos parâmetros das mensagens e adicionar a variável de timestamp.

Localize o arquivo device1.py, e clique duas vezes para abri-lo. Na linha 29, o código da sub-rotina send() será alterado. O código original é:

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

Mas agora deve ser o seguinte:

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

Salve o arquivo e execute novamente o código utilizando o Terminal:

python device1.py

As mensagens irão diretamente para a tabela do Amazon DynamoDB. Para visualizá-los na guia Elementos, você pode visualizar as mensagens que chegam dentro do serviço Amazon DynamoDB. Para isto, busque por DynamoDB na barra de pesquisas da console da AWS. Na tela do serviço, clique em Tabelas, no menu lateral à esquerda, e localize a tabela criada ‘Tcu-Speed’. Selecione a tabela e clique em Visualizar itens.

 

 

Volte ao ambiente do Cloud9 e interrompa a execução no Terminal com Ctrl+C (ou Command+C).

 

Executar uma ação ou acionar um alarme

Você já tem as informações salvas no Amazon DynamoDB, mas e se quiser executar uma ação se uma métrica exceder um determinado limite? As regras podem executar várias ações ao mesmo tempo e em seguida, adicionar uma nova regra para executar o Amazon Simple Notification Service (Amazon SNS). Este serviço permite que você adicione várias ações, que ajudam a integrar a solução de IoT com outros elementos na AWS.

Em seguida, você criará um tópico no SNS, roteará mensagens do AWS IoT Core para o SNS e usará o Amazon Simple Queue Service (Amazon SQS) para visualizar mensagens com falha. A arquitetura até final desta etapa ficará assim:

 

 

Criar Um Tópico No SNS

No console da AWS em Serviços, digite “SNS”.

 

 

Na tela, selecione o menu à esquerda e clique em Tópicos e, em seguida, clique no botão laranja Criar um tópico

Digite os seguintes dados:

  • Nome: SNSAlertaVelocidade
  • Nome de exibição: AlertaVelocidade

Conforme mostrado na tela a seguir e clique em Criar um tópico.

 

 

Depois que o tópico for criado, na tela seguinte, clique em Criar assinatura.

Para criar uma assinatura SMS, você precisa inserir os seguintes dados:

  • Protocolo: SMS
  • Endpoint: (Digite seu número de celular de 12 dígitos com sinal “+” no início)

Clique em Criar uma assinatura.

 

 

Criar Uma Fila No Amazon SQS

Agora, uma fila será criada no SQS. No console da AWS, em Serviços, digite “SQS” e faça login no serviço. Clique em Criar fila.

 

 

O tipo de fila será Padrão. Insira o nome da fila: “FilaAlertasVelocidade”. Todos os outros valores permanecem inalterados. Clique em Criar fila.

 

 

Depois que a fila for criada, clicar no botão laranja Inscrever-se no Tópico do Amazon SNS.

 

 

Na próxima tela, selecione o ARN criado no SNS. Se você tiver vários, você deve encontrá-lo pelo nome que você deu. Em seguida, clique em Salvar.

Nesse ponto, todas as mensagens que chegarem ao tópico do SNS serão colocadas na fila SQS.

Crie Uma Nova Regra no IoT Core

Agora, uma nova regra será adicionada ao AWS IoT Core, que executará uma ação para enviar os dados para o tópico do SNS.

Abra o console do AWS IoT Core, no console da AWS. Na tela principal do AWS IoT, no menu esquerdo, selecione Agir e, em seguida, Regras. Clique no botão azul no canto superior direito Criar.

Na tela seguinte, insira os seguintes valores:

Nome: RegraAlertaVelocidade

Instrução de consulta:

SELECT "Alerta: velocidade maior que 80" as msg from "tcu/vehicle/#" WHERE value > 80

A tela ficará assim:

 

 

Em seguida, na seção Definir uma ou várias ações, clique em Adicionar ação. Na próxima tela, selecione Enviar uma mensagem como notificação por push SNS e mova a tela para baixo até Configurar ação.

Na próxima tela, selecione o SNS que foi criado anteriormente e o tipo de formato deve ser RAW. Clique em Criar função (role), na janela pop-up, digite Iot_SNS_Role e clique em Criar função. Verifique se a política foi anexada na próxima tela e clique em Adicionar ação.

 

 

Clique em Criar regra na parte inferior da tela.

Enviar mensagens para validar o alerta

Novamente, na interface do AWS Cloud9, você precisará executar no Terminal novamente:

python device1.py

Assim que você tiver um valor maior que 80 em Velocidade, a regra será acionada:

 

 

Para exibir as mensagens na fila SQS, retorne ao serviço e clique no botão superior esquerdo para listar as filas:

Na lista de filas, marque a linha: FilaAlertasVelocidade e depois Enviar e Receber Mensagens.

 

 

Na próxima tela, clique no botão “Pesquisar mensagens” para começar a ver as que estão na linha. Esses alertas também chegarão via mensagem SMS para o celular inscrito.

Por fim, encerre o script no AWS Cloud9 para parar de gerar mensagens.

 

Serviço de Device Shadow

O serviço AWS IoT Device Shadow adiciona um item chamado Shadow aos objetos do AWS IoT. O Shadow pode disponibilizar o status de um dispositivo para aplicativos e outros serviços, independentemente de o dispositivo estar conectado ao AWS IoT ou não.

Cada Shadow tem um tópico MQTT e uma URL HTTP que suporta as ações obter, atualizar e excluir. Os Shadows usam documentos JSON para armazenar e recuperar dados. Um documento Shadow contém uma propriedade state que descreve esses aspectos do estado do dispositivo:

  • Desejado: os aplicativos especificam os estados desejados das propriedades do dispositivo atualizando-o.
  • Relatado: os dispositivos relatam seu status atual.
  • Delta: O AWS IoT relata diferenças entre o status desejado (desired) e o relatado (reported) com esse objeto.

É importante considerar que os estados de seus Shadows são dinâmicas e podem ser modificadas por dispositivos, aplicativos e outros serviços em nuvem com as permissões apropriadas. Portanto, essas práticas são recomendadas:

  • Os dispositivos devem gravar somente na propriedade relatada do estado Shadow.
  • Os aplicativos e outros serviços em nuvem devem gravar somente na propriedade desejada ao comunicar solicitações de alteração de estado ao dispositivo por meio do Shadow.

Para saber mais sobre os Shadows com os dispositivos no IoT Core, consulte o seguinte link sobre o serviço de Device Shadows no IoT Core.

Logo, partindo-se do pretexto que é sempre importante trabalharmos com Shadows junto aos nossos dispositivos em prol de uma arquitetura mais resiliente e confiável, vamos agora trabalhar em um código para adicionar um Shadow ao nosso dispositivo criado anteriormente no IoT Core.

Voltemos ao Cloud9. Na seção Terminal, vamos criar outro arquivo no diretório Lab1 com o seguinte comando:

touch fabrica.py

No menu de navegação à esquerda, clique duas vezes no arquivo criado (fabrica.py) para abri-lo e copie o código a seguir.

import sys
import ssl
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTShadowClient, AWSIoTMQTTClient
import json
import time
from random import randint
# IMPORTANTE: MUDE AQUI o nome do dispositivo que foi registrado no AWS IoT Core
ThingName = "Device1"
clientId = "Reader"
# O motor está desligado
MOTOR_STATUS = "OFF"
mqttShadowClient = AWSIoTMQTTShadowClient(clientId)
# Trocar esses parâmetros de Endpoint e certificados:
mqttShadowClient.configureEndpoint("COLOCAR O ENDPOINT CORRETO",8883)
mqttShadowClient.configureCredentials("./root-CA.crt","./Device1.private.key","./Device1.cert.pem")
shadowClient=mqttShadowClient.createShadowHandlerWithName(ThingName,True)
mqttClient = mqttShadowClient.getMQTTConnection()
def updateDeviceShadow():
    global shadowClient
    print ("Modificar status se Shadow")
    shadowMessage = {"state":{"reported":{"MOTOR": MOTOR_STATUS}}}
    shadowMessage = json.dumps(shadowMessage)
    shadowClient.shadowUpdate(shadowMessage, validar_atualizacao, 5)
# Validar se houve atualização
def validar_atualizacao(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("Atualizacao solicitada " + token + " time out!")
    if responseStatus == "accepted":
        print ("Status do motor atualizado com exito!")
    if responseStatus == "rejected":
        print("Solicitacao de atualizacao " + token + " negada!")
# Custom Shadow callback
def customShadowCallback_Delta(payload, responseStatus, token):
    global MOTOR_STATUS
    # Os Tópicos são arquivos JSON e são analisados com json.loads(...)
    payloadDict = json.loads(payload)
    print ("Device Shadow ... OK")
    # Validar os dados enviados
    if "MOTOR" not in payloadDict["state"]:
        print ("Error: Invalid request, device cannot perform action.")
        return
    #  Obter status do mecanismo, executar ação e, em seguida, atualizar o Device Shadow
    status = payloadDict["state"]["MOTOR"]
    if status == "ON":
        print ("Chega a solicitação para ligar o motor.")
        MOTOR_STATUS = status
        updateDeviceShadow()
    elif status == "OFF":
        print ("Parando o motor.")
        MOTOR_STATUS = status
        updateDeviceShadow()
    else:
        print ("Parametros invalidos, enviar 'ON' ou 'OFF'")
# função para codificar textos em Json
def json_encode(string):
        return json.dumps(string)
mqttClient.json_encode=json_encode
# Valores de temperatura aleatórios são enviados
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 ("Mensagem de temperatura PUBLICADA")
    # Os valores de vibração são enviados somente quando o motor está ligado
    if MOTOR_STATUS == "ON":
        vibration = randint(-500, 500)
        message = {
            'vibration' : vibration
        }
        message = mqttClient.json_encode(message)
        mqttClient.publish("data/vibration", message, 0)
        print ("Motor ligado. Enviando dados de vibração")
#Conectar al gateway
mqttShadowClient.connect()
print ("Conectado")
#Set the current motor status in the device shadow
updateDeviceShadow()
# Ver as mudanças nos Deltas
shadowClient.shadowRegisterDeltaCallback(customShadowCallback_Delta)
#Ciclo
while True:
    send()
    time.sleep(5)
mqttShadowClient.disconnect()

Salve o arquivo e faça as seguintes substituições:

Na linha 9, troque o nome do dispositivo para o qual registramos no IoT Core anteriormente, para que o Shadow seja relacionado à ele. No nosso caso, estamos utilizando Device1.

Nas linhas 15 e 16, troque os valores do endpoint e também do certificado corretos para a nossa solução, semelhante a quando feito anteriormente no passo de Modificação do Dispositivo. Assim, os dados podem ser copiados do arquivo “device1.py” criado anteriormente e acessado pelo menu de navegação a esquerda do Cloud9.

Em seguida, é necessário criar outro arquivo para enviar comandos e ligar ou desligar o mecanismo, assim como feito anteriormente para o status do dispositivo. Logo, voltando ao Terminal do Cloud9, execute o seguinte comando:

touch comandos.py

Ainda no Cloud9, no menu de navegação à esquerda, clique duas vezes no arquivo criado, e ao abri-lo copie nele o seguinte 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="Ligar ou desligar o motor: ON / OFF")
 
args = parser.parse_args()
status = args.status
 
# Colocar o nome do dispositivo correto
ThingName = "Device1"
 
 
clientId = "Writter"
mqttc = AWSIoTMQTTShadowClient(clientId)
 
 
# Validar se a região us-east-1 está sendo usada para que o ponteiro funcione
mqttc.configureEndpoint("COLOCAR O ENDPOINT CORRETO",8883)
#
# IMPORTANTE
# Renomeie xyz.private.key e xyz.private.key para os nomes de certificado corretos
mqttc.configureCredentials("./root-CA.crt","./Device1.private.key","./Device1.cert.pem")
mqttc.connect()
 
MOTOR_STATUS = status
 
shadowClient=mqttc.createShadowHandlerWithName(ThingName,True)
shadowMessage = {"state":{"desired":{"MOTOR":MOTOR_STATUS}}}
shadowMessage = json.dumps(shadowMessage)
 
# Enviando a primeira atualização
 
print ("Conectado")
shadowClient.shadowUpdate(shadowMessage,None, 5)
print ("Atualizacao de Shadow enviada")
time.sleep(5)
mqttc.disconnect()

Salve o arquivo e faça as seguintes substituições:

Na linha 18, troque novamente o nome do dispositivo para o qual registramos no IoT Core anteriormente. No nosso caso, estamos utilizando Device1.

Nas linhas 27 e 32, troque os valores do endpoint e também do certificado corretos para a nossa solução, igual feito anteriormente para a configuração do Shadow.

Esse arquivo representa um centro de comando onde você pode iniciar ou parar um mecanismo remotamente, e para sua execução serão utilizados os parâmetros ON ou OFF. Como a comunicação com a fábrica às vezes pode ser perdida, o último estado desejado permanece no AWS IoT Core para que, assim que você tiver conectividade, o estado do dispositivo seja atualizado.

Para ter os dois arquivos em execução, no AWS Cloud9, você pode abrir outra janela do Terminal. No menu superior, clique em Janela -> Novo Terminal e, em seguida, você terá a tela Terminal na parte inferior e outra para cima.

 

 

Execute o seguinte comando na tela do novo Terminal aberto:

python fabrica.py

Na primeira tela, você terá o motor funcionando. Para ver as mensagens que chegam à AWS, acesse AWS IoT Core e, em seguida, em Gerenciar -> Coisas, e clique no nome do dispositivo. Na próxima tela, clique em Device shadows e, em seguida, em Shadow clássico, você verá uma tela semelhante a seguinte:

 

 

Verifica-se que o dispositivo enviou seu estado e sua ultima atualização encontra-se desligado, como definido no código fabrica.py, e assim há confirmação de comunicação e atualização com a nuvem.

De volta ao AWS IoT Core, clique em Testar -> Cliente de teste MQTT, na parte inferior do menu à esquerda.

 

 

E na próxima tela, insira o seguinte texto e clique em Inscrever-se .

 $aws/things/Device1/shadow/update/documents

Este tópico mostrará os documentos JSON que chegam com relação ao Shadow.

Agora, de volta ao AWS Cloud9, na tela inferior do Terminal, executamos:

python comandos.py -a ON

Este comando está alterando o código de comandos para que seja trocado o status do motor para ON, e assim verificar suas atualizações com a nuvem. As seguintes mensagens podem ser verificadas na tela do Terminal criado no Cloud9 anteriormente, onde o script fabrica.py foi executado:

 

 

A mensagem que será exibida no Device Shadow que chega ao tópico inscrito ficará assim:

 

 

Como se pode verificar, há uma diferença entre os estados desired e reported. Essa diferença se deve a atualização do estado do Shadow em relação ao ultimo informado, onde ao longo das atualizações do dispositivo, seu Shadow é atualizado conforme sua última informada, mantendo a rastreabilidade de informações do dispositivo. Este exemplo mostra o uso do Device Shadow no AWS IoT Core.

Cleaning up

Ao fim destes passos, os recursos criados nos serviços mencionados nesta publicação podem ser deletados a fim de evitar qualquer tipo de cobrança indevida sob os mesmos.

 

Conclusão

Este documento mostra como é possível se comunicar com dispositivos usando o AWS IoT Core estabelecendo comunicação segura e definindo políticas de acordo com o que você precisa fazer. Também foram criadas regras para rotear mensagens recebidas e executar ações dentro da AWS com vários serviços. Por fim, explicamos como usar o Device Shadow e como eles podem ajudar os aplicativos a interagir com dispositivos que podem ser desconectados da Internet e, assim, evitar a perda de comandos enviados a eles.

 


Sobre os autores

Breno Silva é Arquiteto de Soluções na AWS, trabalhando para o setor Enterprise. Trabalha com ênfase em Internet das Coisas, e atuou com clientes de varejo, indústria e automotivo. No tempo livre gosta de tocar guitarra, nadar e passar tempo com os amigos.

 

 

 

 

 

Pedro Assumpção é Consultor de Aplicações na AWS, trabalhando em projetos de Aplicação, Modernização e Migração. Trabalha com ênfase em soluções serverless, bancos de dados, e integração de dispositivos com a nuvem e orquestração dos mesmos. Apaixonado por vídeo games, música e motocicletas, frequentemente é encontrado em suas jogatinas, tocando alguma música nova, ou nas estradas por aí.