PROIoT - Introdução à Comunicação via HTTP
This tutorial is not available in English
Introdução
Como pudemos observar no tutorial PROIoT - Introdução à Plataforma, ela é capaz de armazenar dados através de comunicação com o protocolo de rede HTTP, além de outros. Porém, a pergunta que não quer calar é, como fazer de maneira simples e prática o envio de dados para o painel de visualização? A resposta é simples, basta utilizar um dispositivo com conexão à internet para enviar, por exemplo, a leitura de um sensor, com um padrão de mensagem reconhecido.
Neste tutorial vamos aprender a fazer essa comunicação com conectividade Wi-Fi por meio de um NodeMCU, para enviar a temperatura e a umidade ambiente em um intervalo de tempo fixo, através de mensagens com o protocolo HTTP.
Lista de Materiais
Lista completa de produtos
comprarNodeMCU ESP8266-12 V2
Sensor DHT11 de Temperatura e Umidade
Conversor de Nível Lógico RC
Resistor 10kΩ - Pacote com 10 unidades
Protoboard 400 Pontos
WorkPlate 400 - Preta
Cabo USB Micro B 80cm
Jumpers Macho-Macho x40 Unidades
Configurações da Plataforma
Primeiramente, para esse tutorial, devemos criar uma aplicação na seção "Organização". Ao acessar essa seção, você se depara com uma caixa informando o nome de sua organização e os dados dela, como a quantidade de aplicações, tokens de APIs, gateways, e perfis. Com isso na tela, clique sobre o nome da organização para entrar nas suas configurações.
Ao pressionar o botão, você é direcionado automaticamente para a página "Aplicações", onde você pode editar aplicações existentes ou criar novas. Para a criação, pressione o botão "+ Aplicação" e digite um nome para a sua nova aplicação.
Após a criação da aplicação, aproveitando que estamos na seção "Organização", vamos criar um token de API para a segurança de nosso projeto. Para isso, acesse a subseção "Tokens de API" da seção "Organização". Ao acessar essa subseção pela primeira vez, você se depara com uma página vazia, contendo apenas o botão "+ Token", para a criação de uma nova chave de acesso. Pressione o botão e digite o nome desejado para o seu token.
Uma vez criado o token, a chave de acesso é exibida ao lado do nome. Essa chave criada será utilizada posteriormente para o desenvolvimento deste tutorial.
O Token API é único, pessoal e ele é utilizado para garantir a segurança de seu projeto, portanto não o compartilhe.
Após a criação destes dois campos da plataforma, e ao acessar novamente a seção "Organização", é possível observar o indicador exibindo o valor "1" tanto em "Aplicações", quanto em "Tokens de API", como na imagem a seguir.
Criação de Dispositivos e Variáveis
O próximo passo deste tutorial é a criação de um dispositivo. Para isso, devemos acessar a seção "Dispositivos" e pressionar o botão "+ Dispositivo". Ao pressionar esse botão, você é direcionado para uma página de edição, onde você deve selecionar o tipo de dispositivo, neste caso "Dispositivo HTTP". Além disso, é necessário preencher o nome do dispositivo e o seu rótulo, como na imagem abaixo.
O "Rótulo" é utilizado como um diretório primário para o envio das variáveis exibidas, algo parecido com uma pasta dentro de pastas, ou seja, os "Alias" (que serão criados em seguida) estão contidos dentro do rótulo. Após o preenchimento dos dados e a seleção correta do tipo de dispositivo, confirme a criação para que possamos prosseguir para a criação de variáveis. Após a criação, você é direcionado automaticamente para uma página contendo todas as variáveis do dispositivo (por enquanto nenhuma).
Para criarmos a primeira variável do projeto, pressione o botão "+ Variável". Ao pressionar esse botão, é exibida uma página onde devemos preencher o nome da variável, o seu "Alias" e a sua unidade, como na imagem a seguir. Vale lembrar que neste tutorial trabalharemos com o sensor de temperatura e umidade DHT11, portanto temos que declará-las com nomes que representem os valores que serão recebidos.
O "Alias" é o diretório único de cada variável, que é utilizado para direcionar corretamente as variáveis que serão atualizadas com os comandos HTTP. Para esse tutorial, criaremos duas variáveis. Portanto, após a criação da primeira variável, pressione novamente o botão "+ Variável" para criar a segunda variável, como na imagem abaixo. Vale lembrar que é necessário preencher um "Alias" diferente para a segunda variável.
Após a criação das variáveis, é possível observá-las na lista de variáveis de seu dispositivo, anteriormente criado, juntamente com o seu ID exclusivo e o último valor recebido.
Criação e Configuração de Widgets
A última configuração que faremos em nosso projeto é a criação e a configuração de Widgets na seção "Painel" da plataforma. Para isso, é necessário acessar a seção "Painel" e pressionar o botão "+ Widget". Ao pressionar o botão, você é direcionado para a página da imagem a seguir.
A imagem acima demonstra todos os Widgets disponíveis atualmente para a plataforma PROIoT. Neste tutorial utilizaremos o Widget de gráfico de linhas, clicando sobre o ícone do mesmo. Ao selecioná-lo, você é direcionado para a sua página de configuração. Nesta página, é necessário selecionar corretamente as variáveis que serão exibidas no gráfico, neste caso, Temperatura e Umidade. Além disso, é possível alterar a cor de exibição de cada variável para facilitar a visualização dos valores, bem como o nome do gráfico. Também é possível personalizar a exibição, selecionando algumas configurações extras, sendo elas a exibição da legenda, da última atualização, da área e dos pontos, como na imagem abaixo.
Quando finalizada a configuração, você é redirecionado para o painel inicial da plataforma, onde é possível observar o Widget de gráfico criado, porém em uma escala reduzida. É possível ampliar sua visualização ao clicar e arrastar o canto inferior direito do Widget, para ajustar a sua dimensão da maneira que desejar.
Com a configuração de nosso primeiro Widget finalizada, vamos avançar e criar os dois próximos Widgets, individuais para cada uma das variáveis. Para isso, é necessário pressionar novamente o botão "+ Widget", e selecionar o Widget "Métrico", que irá te direcionar para a sua devida página de edição. Nesse Widget é necessário selecionar a variável que será exibida. Também é possível alterar o nome do Widget e sua cor de exibição, como na imagem abaixo. Além disso, você pode selecionar um ícone para facilitar a visualização e entendimento do valor exibido.
Com a configuração finalizada e com o Widget criado, o painel da plataforma é atualizado com os dois exibidores criados. Este segundo Widget criado também pode ser redimensionado para uma melhor visualização. Após a criação para a variável Temperatura, vamos, por fim, criar o exibidor individual da variável Umidade, da mesma maneira da variável anterior, como na imagem a seguir.
Para exibir graficamente a variação de temperatura, adicione um "Gauge Widget", e o configure para receber a variável Temperatura. É possível adicionar faixas de valores com cores diferentes para diversificar o mostrador. Para isso, basta selecionar a opção "+ Adicionar Intervalo", e definir a cor desejada e a faixa de valor a ser definida, como na imagem abaixo.
Já para a exibição gráfica do valor de umidade lido pelo sensor, adicione um "Tanque Widget", e o configure para receber a variável Umidade. Para o "Tanque Widget", podemos definir uma lógica para a sua cor de exibição. Para isso, basta selecionar a opção "Usar faixa de cores personalizada", adicionar faixas de alteração ao selecionar a opção "+ Adicionar Intervalo", e, finalmente, configurar a cor do intervalo de acordo com a faixa desejada, como na imagem a seguir.
Após a criação, configuração e dimensionamento de todos os Widgets como mostrado acima, você tem um painel parecido com o da imagem abaixo.
Vale lembrar que os valores devem ser iniciados zerados, já que ainda não foi feita nenhuma postagem do NodeMCU para a plataforma.
Circuito
Agora que a configuração da plataforma de exibição de dados de nosso projeto está finalizada, é hora de iniciarmos a montagem física de nosso monitor de temperatura e umidade ambiente. Para isso, monte o circuito a seguir.
Para esse projeto, também é possível utilizar o sensor de temperatura e umidade DHT22 porém ainda é necessário o uso do conversor de nível lógico para compatibilizar a tensão de operação do sensor, de 5 V, para 3,3 V do NodeMCU.
Software
Bibliotecas
Para trabalhar com o sensor DHT, é necessário instalar duas bibliotecas, a "Adafruit Sensors" e a "DHT". Para baixar os arquivos das bibliotecas, clique nos botões a seguir.
Caso você não saiba como instalar bibliotecas na Arduino IDE, siga o nosso tutorial Adicionando Bibliotecas a IDE Arduino.
Pacote NodeMCU
Para carregar o código para o NodeMCU, é necessário instalar o pacote da placa na Arduino IDE. Para isso, siga o nosso tutorial Como programar o NodeMCU com Arduino IDE. Além disso, uma das bibliotecas que utilizamos neste tutorial será instalada automaticamente, juntamente com a instalação deste pacote.
Código
Para enviar a leitura de temperatura e umidade ambiente do sensor DHT, copie e carregue o código a seguir para a sua placa.
Entendendo o Código
Primeiramente incluimos as bibliotecas ESP8266WiFi.h
e DHT.h
, instaladas anteriormente, ao código para que possamos utilizar os seus respectivos comandos. Em seguida, declaramos cliente
como um objeto da classe WiFiClient
. Depois, declaramos a variável PINO_DHT
, que armazena o pino que está conectado ao sensor e que é utilizado para declarar o objeto dht
. Esse objeto é uma instância da classe DHT
, em função do pino selecionado e do modelo do sensor (DHT11 ou DHT22). E para finalizar a primeira seção do código, declaramos as variáveis temperatura
e umidade
, que serão responsáveis por armazenar as leituras do sensor, juntamente com a declaração das strings constantes que armazenam o endereço do servidor e a porta de conexão do servidor, assim como a string que será responsável por receber a resposta do servidor de acordo com a mensagem enviada.
Ainda nesta seção temos as strings e variáveis constantes que são utilizadas para o envio da leitura do sensor para a plataforma. As duas últimas variáveis, ESPERA
e ATRASO
, são responsáveis pelo tempo de espera entre o envio de dados, ou seja, entre uma variável e outra, e pelo tempo de espera para o envio de novas atualizações, respectivamente. As strings declaradas acima são dados pessoais de seu projeto, e devem ser alterados de acordo com os seus nomes para que o código seja executado corretamente. As strings REDE
e SENHA
representam o nome e a senha, respectivamente, de sua rede Wi-Fi. As strings TOKEN
, ROTULO
, ALIAS
e ALIAS2
representam os dados que configuramos anteriormente neste tutorial.
Na configuração do código, iniciamos abrindo o monitor serial com a velocidade de 115200 bps (recomendada para o NodeMCU), juntamente com a inicialização do objeto dht
.
Logo após, definimos o modo de trabalho da placa para "estação", e iniciamos a conexão Wi-Fi de acordo com o nome e senha de sua rede Wi-Fi.
Essa conexão com sua rede Wi-Fi é verificada através da condição while(WiFi.status() != WL_CONNECTED)
, que imprime, repetidamente, um "." enquanto a placa não estiver conectada à rede declarada.
Por fim, na configuração do código, o endereço de IP da placa é impresso no monitor serial através do comando Serial.println(WiFi.localIP());
.
No looping do código, estabelecemos conexão com o servidor em sua respectiva porta, e verificamos o sucesso desta conexão. Caso não a placa não tenha se conectado corretamente ao servidor, é impressa uma mensagem de erro. Entretanto, caso a conexão com o servidor tenha sido estabelecida, o código lê as variáveis desejadas do sensor para o envio das mensagens através da função sendData()
, que será explicada posteriormente.
Uma vez com a conexão estabelecida, lemos a temperatura e a umidade ambiente através do sensor DHT, por meio dos comandos temperatura = dht.readTemperature()
e umidade = dht.readHumidity()
, respectivamente. Em seguida, temos uma condição para verificar se a leitura dos valores do sensor (temperatura ou umidade) foi executada corretamente, através da condição if (isnan(umidade) || isnan(temperatura))
. Caso o sensor não esteja funcionando corretamente, é impresso no monitor serial que houve um erro na leitura do sensor. Caso contrário, prosseguimos para o envio dos dados.
Por fim, ainda no looping do código, nós encerramos a comunicação com o servidor através do comando cliente.stop()
, e aguardamos, durante 20 minutos, para reestabelecer conexão com o servidor e enviar novas leituras do sensor.
Após o looping do código, temos a função readResponse()
, que é utilizada na função sendData()
e é responsável por aguardar a resposta do servidor para imprimi-la no monitor serial. O momento em que a função é chamada é armazenado (unsigned long timeIn = millis()
) e comparado com o tempo atual de execução do código (while (timeIn + timeout > millis())
), e, enquanto esse valor armazenado, somado ao valor definido em seu parâmetro (unsigned int timeout
), for maior que a cronometragem de tempo de execução do código, a função entra em uma segunda condição. A condição if (cliente.available())
verifica se o cliente está disponível, durante esse intervalo de tempo. Caso o cliente esteja disponível, sua resposta é lida e armazenada na string resposta
, que é impressa no monitor serial logo em seguida.
A função sendData()
, a última de nosso código, é a principal, e responsável por enviar os valores de temperatura e umidade ambiente para o servidor. As respectivas variáveis são convertidas para strings para serem adicionadas às mensagens HTTP.
Após o tratamento do sensor DHT, temos a conversão da variável ESPERA
para a escala adequada (milissegundos), assim como sua conversão de uma variável inteira para uma string. A conversão de escala da variável é utilizada para a duração de execução da função readResponse()
. Já a conversão da variável inteira para string é usada para determinar o tempo em que a conexão com o servidor é mantida para o envio da segunda mensagem.
Finalmente, temos os comandos que são responsáveis pelo envio do cabeçalho do protocolo HTTP, para enviar as variáveis lidas pelo sensor para a plataforma PROIoT. Para isso, usamos o comando cliente.println()
, juntamente com uma string (dados
), para enviar para o servidor, através do cliente da conexão, um cabeçalho completo com o token API, os Alias e as variáveis lidas corretamente.
Com o conjunto de comandos acima, o NodeMCU envia as mensagens segundo os formatos abaixo.
POST /stream/device/Rotulo/variable/Alias/27.00 HTTP/1.1
Host: things.proiot.network
Authorization: TokenAPI
Connection: Keep-Alive
Keep-Alive: timeout=5, max=5
POST /stream/device/Rotulo/variable/Alias2/59.00 HTTP/1.1
Host: things.proiot.network
Authorization: TokenAPI
Connection: close
Para enviar os dados para o servidor da PROIoT, temos que enviar uma mensagem do tipo POST, juntamente com o seu endereço completo, que se assemelha muito à um diretório de seu computador. Nesta primeira linha, podemos observar a presença do rótulo e do Alias que configuramos anteriormente neste tutorial. Já o último diretório, que seria praticamente o arquivo de seu computador, é a variável lida pelo sensor DHT, ou seja, a temperatura, ou umidade, ambiente. Esse diretório nos é fornecido pela própria plataforma PROIoT, através do seguinte link de exemplo.
https://things.proiot.network/stream/device/{rotulo}/variable/{alias}/{valor}
Caso o conceito de "Rótulo" e "Alias" não tenha ficado claro, basta considerar que eles são os nomes únicos usados internamente pela plataforma, e os demais nomes, como Temperatura
, são apenas informações para você se organizar pelos painéis.
Para finalizar a primeira linha de mensagem do cabeçalho, nós informamos ao servidor a versão do protocolo HTTP com a qual estamos nos comunicando, neste caso a versão "1.1", através do comando HTTP/1.1
. A segunda linha do cabeçalho (Host: things.proiot.network
), é responsável por direcionar a mensagem ao servidor correto, ou seja, direcionar o envio da mensagem para o site da PROIoT.
A terceira linha da mensagem é onde utilizamos o Token API, anteriormente criado, para que o envio da mensagem seja seguro, e para isso utilizamos o comando Authorization: TokenAPI
. A criação do Token API, juntamente com o envio dessa linha, garante que o seu projeto receba apenas as mensagens que tenham em seu corpo a autorização com a senha correta, ou seja, o token criado e atrelado ao seu projeto.
Para encerrar a primeira mensagem, utilizamos o comando Connection: Keep-Alive
, que mantém o servidor aberto por um determinado intervalo de tempo e para o recebimento de um número específico de mensagens. Para configurar o tempo e o número máximo de mensagens para qual o servidor será mantido aberto, usamos a configuração Keep-Alive: timeout=5, max=5
, que mantém a conexão aberta durante 5
segundos para o envio de até 5
mensagens. Já para encerrar a segunda mensagem, nós encerramos a conexão com o servidor através do comando Connection: Close
.
O Que Deve Acontecer
Ao carregar o código para a placa, com todos os dados alterados corretamente, o monitor serial deve exibir as mensagens de conexões e as mensagens enviadas. As respostas que você receberá para cada envio de mensagem devem ser algo similar às respostas abaixo.
HTTP/1.1 200 OK
Server: nginx/1.14.0 (Ubuntu)
Date: Wed, 27 Nov 2019 12:10:18 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 55
Connection: keep-alive
Strict-Transport-Security: max-age=31536000; includeSubdomains
{"error":false,"message":"Variable updated successful"}
HTTP/1.1 200 OK
Server: nginx/1.14.0 (Ubuntu)
Date: Wed, 27 Nov 2019 12:10:23 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 55
Connection: close
Strict-Transport-Security: max-age=31536000; includeSubdomains
{"error":false,"message":"Variable updated successful"}
Como as respostas acima, podemos observar as mensagens de recebimento do protocolo HTTP com o código 200 OK
, informando que as mensagens foram recebidas e interpretadas corretamente, assim como a data e o horário do recebimento das mensagens, e alguns dados adicionais, como, por exemplo, a quantidade de dados. Entretanto, o mais importante para esse tutorial é a última linha da resposta ({"error":false,"message":"Variable updated successful"}
), onde a plataforma PROIoT informa que não houveram erros no recebimento da mensagem, e que a variável foi atualizada corretamente.
Além disso, no painel da PROIoT, você é capaz de observar as variáveis atualizadas nos Widgets que criamos e configuramos anteriormente, como na imagem a seguir.
Indo Além
Agora que tivemos uma introdução sobre como enviar os dados para a plataforma PROIoT através do protocolo HTTP, você já conseguiu imaginar todas as suas possibilidades de uso? Como já aprendemos como enviar os valores de temperatura e umidade, por que não ampliar esse projeto para uma pequena estação meteorológica? Podemos acrescentar a este circuito um Sensor de Pressão e Temperatura BMP180, um Sensor de Chuva e um Sensor de Luminosidade LDR Grande - 10mm, e posicioná-los em um local aberto para receber na plataforma todos esses dados dos sensores.
Conclusão
A PROIoT pode ser uma grande ferramenta para empresas da área da tecnologia, como, por exemplo, empresas com o desenvolvimento de projetos para a Internet das Coisas, ainda mais porque ela permite que você personalize a plataforma para que ela vista as cores da sua empresa.