Painel de Automação com ThingsBoard e ESP8266
Fala galera, tudo bem? Muitas vezes pensamos em como desenvolver uma interface gráfica para nossos sistemas de automação e não sabemos qual plataforma utilizar ou por onde começar. Neste artigo, irei apresentar a plataforma ThingsBoard e ensinar, de forma prática, a criar um painel de automação para controlar seus dispositivos ESP8266. Então, vem comigo?!
Conhecendo a Plataforma ThingsBoard e sua Arquitetura
O ThingsBoard é uma plataforma IoT que permite a integração e o gerenciamento de dispositivos através de uma infraestrutura Web. Ela fornece uma interface de usuário e aplicações através de protocolos como HTTP, MQTT e CoAP, além de diversos recursos que viabilizam a implementação do projeto de automação.
Este sistema permite que você crie clientes, dispositivos, painéis de controle, ativos e outros componentes estabelecendo vínculos entre eles de acordo com seu ambiente de automação. Dessa forma, você pode criar diversos usuários de clientes e conceder a eles o acesso a determinados dispositivos, ativos ou painel de controle. Para exemplificar, apresento, a seguir, um cenário IoT e a descrição de cada elemento do sistema.
Figura 1 – Arquitetura do ThingsBoard
No contexto da plataforma, os elementos são tratados como entidades. O Tenant Administrador é a entidade que gerencia clientes, cria ou possui dispositivos e estabelece o vínculo entre ativos. Em nosso cenário, temos uma casa e seus cômodos, os quais definimos como ativos. Eles são utilizados para criar relações entre si, permitindo que dispositivos e clientes sejam gerenciados para cada ativo.
Nesta hierarquia, o ativo casa contém outros ativos como a sala de estar que contém o dispositivo NodeMCU, responsável por controlar e obter dados do ambiente. Essas informações podem ser acessados pelo Dashboard, painel destinado à visualização dos dados e controle dos dispositivos por meio da interface do usuário. Assim, um cliente pode ter acesso a um ou mais ativos e dispositivos, cabendo ao administrador dar a permissão.
Após essa visão geral da plataforma, iremos apresentar a estrutura do nosso projeto.
Estrutura do Projeto
Neste artigo, ensinaremos como configurar os dispositivos ESP8266 e criar painéis de visualização e controle no ThingsBoard. Não abordaremos as definições de relacionamento de ativos e clientes, pois tornaria os post muito extenso. Portanto, este artigo foi organizado nos seguintes tópicos:
- Funcionamento do Sistema
- Adicionando Dispositivo na Plataforma
- Desenvolvendo Painel de Controle no ThingsBoard
- Código detalhado do Projeto
Para isso, precisaremos, inicialmente, instalar a plataforma em alguma máquina hospedeira ou um servidor em nuvem. O ThingsBoard disponibiliza o serviço para diversos hardwares, como o Raspberry Pi. Entretanto, para fins de simplificação, utilizaremos a versão de demonstração disponível no próprio site da plataforma.
Você pode acessá-la neste link. A seguir, ensinaremos como adicionar um dispositivo no sistema. A seguir, explicaremos como ocorrerá a comunicação do dispositivo com a plataforma.
Funcionamento do Sistema
A plataforma do ThingsBoard possui APIs que fornecem a comunicação com os dispositivos, utilizando protocolos da camada de aplicação. Em nosso projeto, utilizaremos o MQTT para realizar a conexão entre o serviço do ThingsBoard e nosso dispositivo ESP8266.
Para isso, a plataforma dispõe os recursos de telemetria, onde os dispositivos podem enviar seus dados, podendo salvá-los no banco de dados do sistema e o recurso RPC, que permite o usuário enviar chamadas para o dispositivo e vice-versa.
Logo, utilizaremos esses dois recursos para realizar a comunicação. Basicamente, o ESP8266 enviará seus dados obtidos dos sensores em formato JSON para o tópico de telemetria específico “v1/devices/me/telemetry” e deverá se inscrever no tópico de RPC “v1/devices/me/rpc/request/+” por onde receberá os comandos do usuário, podendo respondê-los publicando no tópico “v1/devices/me/rpc/response/$response_id”, onde “$response_id” corresponde ao id do usuário que enviou o comando. A imagem a seguir ilustra como ocorre essa comunicação:
Após a compreensão do sistema, iniciaremos a configuração deste. Mãos à obra!
Adicionando Dispositivo na Plataforma
Para adicionar um novo dispositivo, siga os passos:
- Na página principal, clique em “Devices”.
- Em seguida, clique em Add new item, de símbolo “+” e, depois, em “Add new device”.
- No campo “Name” preencha com o nome do dispositivo, como o exemplo: ESP8266 Sala de Estar. Em seguida, no campo “Device Type” indique que tipo de dispositivo ele é, no caso: CONTROLE.
- Por último, clique em “ADD”.
Os passos descritos podem ser acompanhados na imagem a seguir:
Figura 3 – Adicionando novo dispositivo na plataforma ThingsBoard
Pronto, você acabou de adicionar um novo dispositivo. Clicando sobre ele você poderá visualizar e editar suas características, como seus atributos, dados de telemetria, relacionamentos e outros. Um dos dados essenciais para a comunicação é seu “Access Token”, disponível na guia “Details”.
Ele será necessário para estabelecer a comunicação e obter os dados deste dispositivo. A seguir, ensinaremos como criar o painel de visualização e controle do dispositivo que acabamos de criar.
Desenvolvendo Painel no ThingsBoard
Para criarmos um painel de visualização e controle, devemos realizar os seguintes passos:
- Na página principal, clique em “Dashboards”.
- Em seguida, clique em Add new dashboard, de símbolo “+” e, depois, em “Create new dashboard”.
- No campo “Title” preencha com o nome do painel, como o exemplo: Sala de Estar. Cada painel criado pode ser representado por um ambiente que pode ser composto por um ou mais dispositivos.
- Em seguida, clique em “ADD” para criarmos nosso painel.
Clicando sobre eles temos acesso aos widgets do painel. Por enquanto, ainda não temos nenhum. Os diversos tipos de widgets fornecem a visualização dos dados e comandos para controlar nossos dispositivos.
Entretanto, para incluí-los em nosso painel precisamos, primeiramente, criar aliases de entidade, ou seja, nomes que identificam os dados e estão vinculados a algum dispositivo. Assim, continue com os seguintes passos:
- Dentro do painel recém criado, clique em “Enter edit mode”, cujo símbolo é um lápis no canto inferior direito.
- Clique na opção “Entity Aliases”, em seguida, clique no botão “ADD ALIAS”.
- No campo “Alias name” defina com os dados que utilizaremos do dispositivo, no caso: Controle Luz. Em seguida, no campo “Filter type” escolha a opção “Entity List”. Na guia “Type” selecione ”Device” e em “Entity List” selecione o dispositivo que criamos: ESP8266 Sala de Estar.
- Repita o passo anterior adicionando o alias Temperatura e o alias Umidade.
- Por fim, clique em “Save” para adicioná-los.
A figura seguinte ilustra resumidamente os passos descritos:
Figura 4 – Configurando Painel no ThingsBoard
Feito isso, podemos criar nossos widgets de visualização e controle, descritos a seguir.
Criando Widgets de Visualização e Controle
Iremos criar três tipos de widgets para os respectivos aliases inseridos. Dessa forma, criaremos um botão para controlar a luz do ambiente e dois gráficos para visualizar a temperatura e umidade.
Em geral, adicionar um novo widgets consiste em três passos: escolhermos seu tipo, vinculá-lo ao alias de entidade que criamos e configurá-lo.
Primeiro, criaremos o botão de controle da luz seguindo os passos:
- Clique na opção “Add New Widget”.
- Na guia “Select widgets bundle” escolha a opção “Control widgets” e escolha o widget “Switch control”.
- Em seguida, na guia “DATA”, temos o campo “Target device” onde selecionamos o alias que criamos denominado Controle Luz.
- Na guia “ADVANCED” definiremos alguns parâmetros. No campo “Switch title” inserimos o nome do widget: Luz Sala de Estar. No campo “Convert value function” que possui uma caixa de entrada com um código em javascript, substituiremos pelo seguinte código: return {‘enabled’ : value, ‘gpio’ : 2}
- Por fim, clique em “ADD”.
Agora, realizaremos os mesmos passos para a criação dos outros dois widgets, modificando apenas os parâmetro indicados na figura a seguir:
Figura 5 – Adicionando Widgets no Painel
Após a realização dos passos descritos, devemos ter um painel com o seguinte visual:
Figura 6 – Visualização Final do Painel
Acredite, estamos quase lá! Acabamos de concluir as configurações de nossa plataforma. Desse modo, os próximos tópicos irão descrever os componentes necessários, a montagem e o código do projeto detalhado.
Componentes do Projeto
A seguir, descrevo os componentes necessários para a execução do projeto:
Estes e outros módulos podem ser encontrados em nosso site, clicando aqui.
Montagem do Circuito
Com os componentes em mãos, faremos a montagem do nosso circuito seguindo a imagem abaixo:
Figura 7 – Esquema de ligação no NodeMCU
De acordo com o esquema, utilizamos o pino D4 ligado ao módulo relé e o pino D2 conectado ao sensor DHT22. A seguir, apresentamos o código detalhado do nosso projeto.
Código Detalhado do Projeto
/*
Projeto: Painel de Automação com ThingsBoard e ESP8266
Autor: Daniel Fiuza - AutoCore Robótica
Data: 20/03/2020
Código de Domínio Público
*/
#include "DHTesp.h"
#include <ArduinoJson.h>
#include <PubSubClient.h>
#include <ESP8266WiFi.h>
// Configurações do Wifi
#define WIFI_AP "Seu-ssid"
#define WIFI_PASSWORD "Sua-senha"
// Configurações do ThingsBoard
// O TOKEN do dispositivo é obtido na
// guia Devices -> ESP8266 Sala de Estar
#define TOKEN "Acces-Token-do-Dispositivo"
// Endereço do servidor ThingsBoard
char thingsboardServer[] = "demo.thingsboard.io";
// Tópico onde serão publicados os dados do sensor
char topic_publish[] = "v1/devices/me/telemetry";
// Instancia objeto dht para uso
// do módulo DHT22
DHTesp dht;
// Instancia objeto wifiClient
WiFiClient wifiClient;
// Instancia cliente MQTT 'client'
PubSubClient client(wifiClient);
// Status de conexão Wifi
int status = WL_IDLE_STATUS;
// Variável para controle do
// intervalo de tempo
unsigned long last_time;
void setup()
{
// Inicia porta serial
Serial.begin(115200);
Serial.println();
// Configura GPIO 2 como saída para acionar o relé
// Pino D4 NodeMCU --> GPIO 2 IDE Arduino
pinMode(2, OUTPUT);
// Configura GPIO 4 como entrada para o sensor DHT22
// Pino D3 NodeMCU --> GPIO 4 IDE Arduino
dht.setup(4, DHTesp::DHT22);
delay(10);
// Função que inicia a conexão com o Access Point
InitWiFi();
// Em seguida, configura a conexão MQTT
client.setServer( thingsboardServer, 1883 );
// Define função on_message como retorno de chamada MQTT
// Processa as mensagens recebidas do servidor
client.setCallback(on_message);
}
void loop()
{
// Se o cliente MQTT não tiver conectado, executa função reconnect()
if ( !client.connected() ) {
reconnect();
}
// Mantém a conexão MQTT aberta com o thingsboard
client.loop();
// Enviar dados do sensor periodicamente
// Se o intervalo de tempo for maior que 1s
if ( millis() - last_time > 1000 ) {
// Envia dados do sensor ao ThingsBoard
sendTemperatureAndHumidity();
last_time = millis();
}
}
/*
* Recebe os comandos do ThingsBoard,
* Processa a mensagem,
* Executa o comando,
* Retorna o status do relé para o servidor.
*
* Exemplo de mensagem Json recebida:
* {
* "method" : "setValue",
* "params" : {
* "enabled": true,
* "gpio" : 2
* }
* }
*/
void on_message(const char* topic, byte* payload, unsigned int length) {
// Variável que receberá a mensagem da variavel payload
char message_json[length + 1];
// Copia os bytes da payload para a variavel message_json
strncpy (message_json, (char*)payload, length);
// Define o terminador da string com o caracter nulo '\0'
// Identificando o fim da string.
message_json[length] = '\0';
// Cria a variável Json data de tamanho 200 bytes
StaticJsonDocument<200> data;
// Desserializando a mensagem da variável message_json
DeserializationError error = deserializeJson(data, message_json);
// Se houver erro ao desserializar, informa.
if (error) {
Serial.print("Erro ao desserializar Json");
return;
}
// Status do gpio
boolean status_gpio;
// Recebe parâmetro "method"
String methodName = String((const char*)data["method"]);
// Recebe parâmetro "enable"
boolean enabled = data["params"]["enabled"];
// Recebe parâmetro "gpio"
int pin = data["params"]["gpio"];
// Verifica se o método recebido é "setValue"
if(methodName.equals("setValue")){
// Se enable for true, então aciona relé
// Note que o acionamento é com nível lógico 0
if(enabled){
digitalWrite(pin, LOW);
// Atualiza status do pino
status_gpio = true;
}
// Caso contrário, desliga relé
else{
digitalWrite(pin, HIGH);
status_gpio = false;
}
// Variável que recebe o tópico
// Ex. tópico: v1/devices/me/rpc/request/$request_id
String responseTopic = String(topic);
// Substitui a palavra request por response, atualizando o tópico
// Ex. tópico atualizado: v1/devices/me/rpc/response/$request_id
responseTopic.replace("request", "response");
// Cria variável Json send_data
StaticJsonDocument<200> send_data;
// Cria mensagem Json na variável send_data
send_data["method"] = "getValue";
JsonObject obj = send_data.createNestedObject("params");
obj["enabled"] = status_gpio;
obj["gpio"] = pin;
/*
* Formato da mensagem criada:
* {
* "method" : "getValue",
* "params" : {
* "enabled" : true,
* "gpio" : 2
* }
* }
*
*/
String send_payload;
// Serializa a variável send_data para string send_payload
serializeJson(send_data, send_payload);
// Por fim, publica no tópico atualizado e mensagem criada
client.publish(responseTopic.c_str(), send_payload.c_str());
}
}
// Inicia conexão Wifi
void InitWiFi() {
Serial.println("Conectando-se ao AP ...");
// Inicia conexão com Wifi
WiFi.begin(WIFI_AP, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("Conexão Wifi estabelecida");
}
// Reconecta cliente MQTT ao ThingsBoard
void reconnect() {
// Se o cliente MQTT não estiver conectado, verifica conexão wifi e mqtt
while (!client.connected()) {
status = WiFi.status();
// Caso não esteja conectado ao wifi, inicia conexão
if ( status != WL_CONNECTED) {
WiFi.begin(WIFI_AP, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("Connected to AP");
}
Serial.print("Conectando-se ao ThingsBoard ...");
// Inicia conexão MQTT
// Função connect(clientId, username, password)
if ( client.connect("ESP8266 Device", TOKEN, NULL) ) {
// Imprime resultado da conexão MQTT, indicando que foi estabelecida
Serial.println( "[MQTT DONE]" );
// Inscreve para receber as solicitações RPC
client.subscribe("v1/devices/me/rpc/request/+");
} else {
// Imprime resultado da conexão MQTT, indicando que não foi estabelecida
Serial.print( "[MQTT FAILED] [ rc = " );
Serial.print( client.state() );
Serial.println( " : retrying in 5 seconds]" );
// Aguarda 5 segundos antes de se reconectar
delay( 5000 );
}
}
}
/*
* Envia os dados da Temperatura e Umidade
* A mensagem terá o seguinte formato Json:
* {
* "temperature" : 28.70
* "humidity" : 87.80
* }
*
*/
void sendTemperatureAndHumidity(){
// Recebe valor da umidade
float humidity = dht.getHumidity();
// Recebe valor da temperatura
float temperature = dht.getTemperature();
// Se aquisição tiver sido bem sucedida
if (dht.getStatusString() == "OK"){
// Cria variável Json data
StaticJsonDocument<200> data;
// Cria mensagem Json na variável data
data["temperature"] = temperature;
data["humidity"] = humidity;
// Cria string payload
String payload;
// Serializa a variável data para string payload
serializeJson(data, payload);
// Por fim, publica esta string no tópico especificado
client.publish(topic_publish, payload.c_str());
// Imprime o tópico e a mensagem enviados
Serial.print("Publish in topic: ");
Serial.print(topic_publish);
Serial.print(" , message: ");
Serial.print(payload.c_str());
Serial.println();
}
else {
// Imprime erro caso não tenha obtido os dados do sensor.
Serial.print("Erro ao obter dados do DHT");
}
}
Resultado do Projeto
Como resultado, deixo o vídeo onde demonstro nosso painel de automação e realizo o controle do dispositivo conforme descrevemos neste artigo.
Então, gostou do nosso projeto? Caso haja alguma dúvida, comente abaixo. Confira mais conteúdos em nosso blog

Olá Daniel,
Uma dúvida, o relé utilizado no projeto foi um rele ativado por 3V? Caso meu relé seja ativado por 5V, seria uma boa prática utilizar o pino VIN?
Olá, Allef. Seja bem-vindo! Sim. Sugiro utilizar os módulos de 3.3V. Utilizar tensões diferentes pode gerar acionamentos inconsistentes do módulo relé. Porém, caso já tenha adquirido um módulo de 5V, você deve conectar o Vin do módulo ao 5v da fonte ou da placa de desenvolvimento ESP, entretanto, deve atentar-se à corrente máxima que o regulador de tensão da placa pode fornecer. Portanto, para o controle de mais de um relé sugiro utilizar uma fonte separada e não a alimentação 5v do ESP. Além disso, para o acionamento dos módulos de 5V (pino IN) você terá que realizar algumas alterações, uma vez que a saída dos pinos do ESP são de 3.3V e o módulo espera 5V. Neste caso, você pode modificar o transistor smd e o resistor que limita a corrente de base, como sugere este artigo, ou adicionar um hardware extra como um conversor de nível lógico disponível neste link assim como um circuito transistorizado. Espero tê-lo ajudado. Caso tenha mais dúvidas, estou à disposição.