Neste tutorial vou explicar como configurar e instalar os serviços para coletar, armazenar e visualizar os dados de um sensor Arduino/ESP8266
O interessante desse tutorial é que vamos trabalhar com diversos conceitos e softwares, numa visão ampla de como podemos nos comunicar no ambiente IoT.
Vamos abordar os seguintes tópicos:
- MQTT (Eclipse Mosquitto)
- InfluxDB
- Telegraf
- Grafana
O que é MQTT?
O protocolo MQTT (MQ Telemetry Transport) é um protocolo extremamente simples e leve desenvolvido para comunicação de dispositivos de baixa banda, grande latência ou pouca confiabilidade.
Eclipse Mosquitto será o servidor escolhido para a comunicação entre nossa aplicação e o sensor, propriamente dito.
Para entender o Mosquitto, vou introduzir basicamente como ele funciona, os conceitos de Broker, Subscribe, Publisher e Topic. Isso é o bastante por hora.
Vamos supor que você tenha dois dispositivos IoT, por exemplo, um ar condicionado e um sensor de temperatura, e você queira conectar os dois.
No ar condicionado você precisa receber as informações da temperatura na casa (ou fora dela). Além disso, precisamos também enviar valores como voltagem interna do ar, a quanto tempo ele está ligado, e termos acesso a isso por meio de um celular, por exemplo.
Já no sensor de temperatura, você não precisa receber nenhum valor, apenas enviar a temperatura, para que estes valores sejam acessados pelo ar condicionado ou qualquer outro dispositivo.
Nesse exemplo, o ar condicionado seria um subscribe (recebe os valores de um determinado tópico, neste caso a temperatura) e publish (envia valor do tempo ligado).
No Mosquitto isso é extremamente simples de ser feito
Instalar o Mosquitto
Vamos instalar o Mosquitto em um Raspberry Pi, porém você pode criar o servidor em windows ou em qualquer outro SO.
Você pode fazer o download no link https://mosquitto.org/download/
Para instalar no Rasbian você entra com os comandos:
wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key
sudo apt-key add mosquitto-repo.gpg.key
Fazemos agora o repositório disponivel no apt
cd /etc/apt/sources.list.d/
Agora adicionamos as dependências
sudo wget http://repo.mosquitto.org/debian/mosquitto-wheezy.list
sudo wget http://repo.mosquitto.org/debian/mosquitto-jessie.list
Atualizamos as informações e instalamos o pacote
apt-get update
apt-get install mosquitto
Por padrão o mosquitto ja vem pré-configurado. Caso você queira alterear essas configurações, você deve editar o arquivo /etc/mosquitto/mosquitto.conf. Mais detalhes você encontra na documentação https://mosquitto.org/man/mosquitto-conf-5.html
Publish e Subscribe
Vamos criar nosso primeiro teste de Publish e Subscribe.
As mensagens no MQTT são publicadas em tópicos. Não existe necessidade de configurar cada tópico, publicar nele já é o bastante.
A estrutura dos tópicos são divididas numa hieraquia semelhante a diretórios: sensors/COMPUTER_NAME/temperature/HARD_DRIVE_01
Sendo assim, podem existir diversos tópicos, para diferentes sensores e dispositivos. Caso voce queira ouvir todos os tópicos em uma determinada camada, voce pode acionar o caractere # ou +
Subscrever por exemplo no topico: sensors/COMPUTER_NAME/temperature/#
recebe todas a mensagens publicadas na hierarquia
sensors/COMPUTER_NAME/temperature/
Mais informações você pode conferir na documentação do Mosquitto
Para “ouvir” uma mensagem vamos usar o comando mosquitto_sub
mosquitto_sub -h localhost -t "sensor/temperatura"
Os parâmetros usados:
-h: Hostname
-t: Tópico
Até aqui você não vai receber nada no terminal. Vamos então abrir uma nova janela e publicar uma mensagem no tópico sensor/temperatura e ver se a comunicação está mesmo funcionando.
mosquitto_pub -h localhost -t "sensor/temperatura" -m "valor:15.5"
Ótimo! Já temos nosso servidor MQTT funcionando. Caso você queira também pode baixar um aplicativo chamado MQTT Dash e receber os dados pelo celular. Lembre-se que caso você queira habilitar o servidor para acesso externo, você tem que fazer um port forward no seu roteador. A porta padrão do Mosquitto é a porta 1883.
Criando aplicação no ESP8266
Agora vamos criar uma aplicação no ESP8266 que leia os valores de temperatura e pressão de um módulo BMP180 e envie esses valores para o nosso broker.
O código é bem simples e você pode fazer o download aqui. Lembre-se de fazer os downloads das bibliotecas. No comentário do código fonte você encontra os links
// This example uses an ESP8266 Board // to connect to MQTT and send BMP180 data // BMP180 wiring: // SCL -> D1 // SDA -> D2 // // MQTT library: https://github.com/256dpi/arduino-mqtt // Adafruit_BMP085: https://github.com/adafruit/Adafruit-BMP085-Library // by Hugo Rezende #include <Adafruit_BMP085.h> #include <ESP8266WiFi.h> #include <MQTT.h> #ifndef STASSID #define STASSID "yourWifiSSID" #define STAPSK "yourWifiPassword" #endif const char* ssid = STASSID; const char* password = STAPSK; WiFiClient net; MQTTClient client; Adafruit_BMP085 bmp; unsigned long lastMillis = 0; uint8_t LED_Pin = D4; void connect() { Serial.print("Checking wifi..."); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); //Blink the led until wifi connects digitalWrite(LED_Pin, HIGH); // Turn the LED on delay(50); digitalWrite(LED_Pin, LOW);// Turn the LED off delay(50); delay(100); } Serial.print("\nConnecting..."); while (!client.connect("arduino", "try", "try")) { Serial.print("."); delay(1000); } Serial.println("\nConnected!"); } void messageReceived(String &topic, String &payload) { Serial.println("incoming: " + topic + " - " + payload); } void setup() { pinMode(LED_Pin, OUTPUT); Serial.begin(115200); WiFi.begin(ssid, password); if (!bmp.begin()) { Serial.println("Could not find a valid BMP085 sensor, check wiring!"); while (1) {} } // Connecting to the MQTT server // Note: Local domain names (e.g. "Computer.local" on OSX) are not supported by Arduino. // You need to set the IP address directly. client.begin("192.168.0.100", 1883 ,net); // here you insert the IP/domain of the MQTT server and the port connect(); } void loop() { client.loop(); delay(10); // fixes some issues with WiFi stability if (!client.connected()) { connect(); } // publish a message roughly every second. if (millis() - lastMillis > 1000) { lastMillis = millis(); // sending values to topics in a JSON format client.publish("sensor/temperatura", "{\"value\": "+ String(bmp.readTemperature()) +"}" ); client.publish("sensor/pressao", "{\"value\": "+ String(bmp.readSealevelPressure()) +"}" ); } }
Assim que o codigo for carregado no ESP8266, ele já começará a enviar as leituras para o MQTT. Note aqui que é importante configurar corretamente o IP do seu Raspberry (ou da máquina que esteja rodando o Mosquitto) na linha client.begin(“192.168.0.10”, 1883 ,net);
Agora é só rodar o terminal, e subscrever no tópico, que você ja começa a ver os dados no terminal.
mosquitto_sub -h localhost -t 'sensor/temperatura'
InfluxDB
Para fazer a persistência dos dados e conectar o Grafana, vamos usar o InflluxDB que é um banco de dados desenvolvido especialmente para armazenamento de time-serie data.
Para instalar siga os comandos:
curl -sL https://repos.influxdata.com/influxdb.key | sudo apt-key add - echo "deb https://repos.influxdata.com/debian stretch stable" | sudo tee /etc/apt/sources.list.d/influxdb.list
Depois instalamos o Influx
sudo apt update
sudo apt -y install influxdb
Agora vamos iniciar o Influx e criar os usuários no banco de dados.
sudo service influxdb start
influx -execute "CREATE USER "telegraf" WITH PASSWORD 'suasenhatelegraf' WITH ALL PRIVILEGES;"
influx -execute "CREATE USER "grafana" WITH PASSWORD 'suasenhagrafana' WITH ALL PRIVILEGES;"
Instalando Telegraf
Precisamos de um client que receba os dados do nosso servidor MQTT e persista no InfluxDB. Para isso existe um plugin chamado Telegraf que após configurado faz isso de forma automática.
sudo apt -y install telegraf
Você pode fazer o download direto aqui
Agora temos que configurar o Telegraf para capturar as mensagens dos tópicos. Para isso devemos abrir o arquivo /etc/telegraf/telegraf.conf
Na linha [[inputs.mqtt_consumer]] você deve descomentar as seguintes linhas, e inserir os tópicos que deseja ouvir:
[..]
# Read metrics from MQTT topic(s)
[[inputs.mqtt_consumer]]
servers = ["localhost:1883"]
## MQTT QoS, must be 0, 1, or 2
qos = 0
## Topics to subscribe to
topics = [
"sensor/temperatura",
"sensor/pressao",
]
[..]
data_format = "json"
[..]
Devemos cadastrar os tópicos que vamos conectar e setar o data_format como JSON (existem outros formatos e você pode ver aqui). Como nosso servidor MQTT não requer nenhuma autenticação, nao é necessario inserir nada na parte de usuário/senha, mas você pode estudar a documentação do Mosquitto e introduzir essa feature.
Outra parte que devemos alterar são os dados de autenticação que o Telegraf irá utilizar para salvar os dados no Influx:
# Configuration for influxdb server to send metrics to
[[outputs.influxdb]]
## The HTTP or UDP URL for your InfluxDB instance. Each item should be
## of the form:
## scheme "://" host [ ":" port]
##
## Multiple urls can be specified as part of the same cluster,
## this means that only ONE of the urls will be written to each interval.
# urls = ["udp://localhost:8089"] # UDP endpoint example
urls = ["http://localhost:8086"] # required
## The target database for metrics (telegraf will create it if not exists).
database = "esp8266" # required
## Name of existing retention policy to write to. Empty string writes to
## the default retention policy.
retention_policy = ""
## Write consistency (clusters only), can be: "any", "one", "quorum", "all"
write_consistency = "any"
## Write timeout (for the InfluxDB client), formatted as a string.
## If not provided, will default to 5s. 0s means no timeout (not recommended).
timeout = "5s"
username = "telegraf"
password = "suasenhatelegraf"
## Set the user agent for HTTP POSTs (can be useful for log differentiation)
# user_agent = "telegraf"
## Set UDP payload size, defaults to InfluxDB UDP Client default (512 bytes)
# udp_payload = 512
[...]
As partes importantes são URL, database, timeout, username e password. Lembre-se de utilizar a mesma senha que você usou ao criar o usuario no InfluxDB.
A próxima etapa é testar o influxdb e o telegraf e conferir se os dados estão sendo armazenados. Após salvar as configurações você deve reiniciar os serviços:
sudo service influxdb restart
sudo service telegraf restart
Agora você pode verificar se os serviços estão rodando:
sudo service influxdb status
sudo service telegraf status
Ambos os serviços estão rodando normalmente.
Se o seu ESP8266 está conectado e enviando os valores para o servidor MQTT, você pode conferir se já suas medições estão de fato aramazenadas no InfluxDB. Para isso você deve iniciar o Influx, escolher o banco de dados e checar as informações.
Para isso vamos entrar no terminal do Influx:
influx
>SHOW DATABASES
Caso o banco de dados “esp8266” nao apareca voce deve cria-lo:
CREATE DATABASE esp8266
USE esp8266
SHOW MEASUREMENTS
Quando você entrar com a query SHOW MEASUREMENTS, se todas as configurações estiverem corretas, você deve ver uma tabela de medições chamada mqtt_consumer. Isso indica que está tudo certo, o ultimo passo é criar a dashboard no Grafana.
Configurando Grafana para receber os dados do MQTT/InfluxDB
Depois de criar uma conta no Grafana, voce deve iniciar uma instância. Feito isso, você terá uma url do tipo https://usuario.grafana.net/
Agora você deve linkar o data source com o seu RaspberryPi (ou na maquina onde você fez todo o processo do InfluxDB).
Um ponto importante e enjoado quando fazemos tudo isso com maquinas locais, é que você deve agora criar uma porta de direcionamento no seu roteador, para que o InfluxDB seja acessado externamente. Se o IP da sua internet não é fixo, é interessante que você instale o No-Ip no RaspberryPi. Seguem aqui as instruções.
No meu roteador eu coloquei as segintes configurações:
Agora você pode acessar tanto seu servidor MQTT quanto o InfluxDB externamente via endereço.no-ip.xxx:numero_da_porta
Configurando agora o datasource do Grafana
Em URL você vai colocar o seu IP ou o endereço do seu No-Ip, seguido da porta externa que você direcionou no seu roteador (no meu caso seria a 8086 mesmo)
Em InfluxDB Details você irá inserir o nome da sua base de dados “esp8266”, usuario e a senha que você criou anteriomente. (“grafana”/ “suasenhagrafana”). Se estiver tudo ok, salve e teste a conexão
Agora você só precisa inserir uma dashboard e criar uma query. Os dados já vao auto carregar no criador de querys e você só precisa escolher o mqtt_consumer, e especificar o tópico no WHERE
Pronto, agora é so criar os paineis com os dados e as configurações que desejar
Se ficou alguma dúvida ou sugestão é só comentar! 😀