Dashboard com grafana e MQTT

Arregace as mangas, porque esse é um trabalho “daqueles”. Precisei fazer um dashboard com Grafana e MQTT. Parecia que tudo seria rápido e tranquilo, considerando meus artigos anteriores sobre Grafana. Bem, não foi nem rápido e nem tranquilo, mas sem dúvidas foi satisfatório. Além do dashboard, fiz a integração com MQTT e alarmes recebidos no Telegram. Bom ou não? Bora começar.

O princípio dessa configuração é seguindo a documentação do projeto Kotori, mas vou descrever o ambiente primeiro.

Cenário

Pesquisando aqui no blog você encontrará “montes” de tutoriais sobre a utilização de MQTT para diversas plataformas. Se nunca experimentou o MQTT antes, não é por esse artigo que você deve começar.

Também escrevi alguns artigos sobre Grafana com collectd, Grafana com graphite, mas esse é o primeiro tutorial de Grafana e MQTT.

Considerando que queremos fazer telemetria utilizando Grafana e MQTT, devemos configurar nossos dispositivos para enviar dados a um broker. O broker deverá ser próprio, por razões descritas mais adiante. O projeto fiz para gerir Raspberry Pi, por isso se você está procurando uma maneira simples de utilizar MQTT no Raspberry, parabéns, achou!

Além do artigo do parágrafo anterior, vou adicionar a este um script de gerenciamento. Siga com a leitura e não se preocupe com o entendimento agora, apenas visualize que teremos:

  • Um Raspberry publicando em nosso broker rodando Grafana e MQTT.
  • Um broker MQTT Mosquitto.

Na parte de software teremos:

  • Um shell script de publicação periódica rodando como serviço no Raspberry Pi.
  • Um broker Mosquitto instalado em um servidor, seja local ou remoto.
  • Um banco de dados time series – o InfluxDB, instalado no broker.
  • Grafana, instalado através do projeto Kotori.
  • Uma bridge feita em Python, para traduzir e transladar os dados entrantes.

Ainda no broker, adicionalmente configuraremos um gerente de alarmes; no caso, optei por enviar os alarmes por Telegram, fazendo um bot. Já escrevi sobre bot Telegram nesse artigo.

É um trabalho consideravelmente longo, feito no Ubuntu 20.04 – codinome “focal”. Iniciemos.

Instalação do Kotori para usar o Grafana e MQTT

Vamos começar pelo broker. Siga o tutorial desse artigo para configurar o Mosquitto e depois continue desse parágrafo.

Na parte de instalação não tem muito segredo, o projeto Kotori tem um guia de instalação muito claro. Só que eu usei como “facilitador”, depois baixei o pacote .deb mais atual do Grafana e o instalei por cima.

Timezone

Como vamos usar banco de dados time series entre o Grafana e MQTT, será fundamental ter o horário do servidor devidamente ajustado. Talvez eu tenha exagerado nos processos, mas vamos lá.

#sempre como root. Daqui por diante não vou digitar "sudo bla,bla,bla". Faça assim:
sudo su
timedatectl set-ntp true

Adicionalmente, instalei o ntpdate e fiz a configuração:

apt-get install ntpdate
ntpdate-debian

Se estiver em um servidor remoto e tiver problemas com timezone, configure com o próprio timedatectl. Verifique a saída:

grafana e MQTT - timezone

O meu já está configurado, mas com essa saída já identificamos qual a configuração utilizada. Claro que para ver se a hora está certa podemos simplesmente utilizar o comando date. Só que isso não garante a timezone.

Estando errado, liste as timezones para definir a sua. No meu caso, utilizei America/Sao_Paulo.

timedatectl set-timezone your_time_zone

Versões mais antigas do sistema utilizam o tradicional tzdata. Se for seu caso, siga o procedimento abaixo:

echo "America/Sao_Paulo" >/etc/timezone

E então reconfigure de maneira direta e explícita o novo fuso horário:

dpkg-reconfigure --frontend noninteractive tzdata

Pacotes necessários adicionais

Alguns pacotes surgirão como dependências em algum momento, por isso vou adicionar todos eles aqui para evitar problemas e tempo de depuração para descobrir o “quê” não funcionou. De nada.

apt-get update && apt-get install  node-grunt-cli adduser libfontconfig1 pm2 npm python3-pip grafana net-tools python2.7 python2.7-minimal python-requests python3-requests python-dateutil mosquitto mosquitto-clients

Também:

apt-transport-https software-properties-common wget gnupg

Adicione o repositório de pacotes para sua distribuição. No caso do Ubuntu, troque o codinome para a respectiva versão:

apt-add-repository 'deb https://packages.elmyra.de/elmyra/foss/debian/ bionic main foundation'

Novamente, atualize a base de pacotes:

apt-get update

Instalação do Kotori

Agora vamos à instalação do Kotori. Também vou descrever a instalação de alguns pacotes que, se tudo estiver bem, já estarão instalados e a mensagem informando isso deverá ser mostrada. De outro modo, os pacotes serão instalados.

apt install --install-recommends kotori

Os pacotes que já deverão existir nesse ponto:

apt-get install grafana grafite influxdb

Atualização forçada do Grafana:

wget https://dl.grafana.com/oss/release/grafana_7.1.0_amd64.deb
dpkg -i grafana_7.1.0_amd64.deb

Plugins do Grafana:

grafana-cli plugins update-all
grafana-cli plugins install  briangann-gauge-panel
grafana-cli plugins install grafana-image-renderer

Ative os serviços grafana-server e influxdb:

systemctl enable influxdb grafana-server
systemctl start influxdb grafana-server

Se seu broker irá rodar em um processador ARM (seja Raspberry, Banana, Orange etc), tem uma compilação recomendada pelo projeto. Execute o comando a seguir APENAS SE O SETUP FOR EM UM ARM:

apt install --install-recommends kotori-standard

Depois, você pode dar sequência no Kotori por esse link. Eu prefiro partir para os “finalmentes”.

Configurações adicionais

Mais pacotes!

pip3 install --upgrade mqtt2influxdb

Tendo já o broker configurado e rodando (independente do Kotori), deveremos ainda seguir alguns passos extras. Crie o arquivo mqtt2influxdb.yml com um conteúdo similar a esse:

mqtt:
  host: 127.0.0.1
  port: 1883

influxdb:
  host: 127.0.0.1
  port: 8086
  database: nome_da_base_criada_no_influxdb

points:
  - measurement: CPU
    topic: /topico
    fields:
      value: $.payload
    tags:
      id: $.topic[1]
      channel: $.topic[3]

Mais alguns pacotes e finalizamos a configuração, seja paciente:

npm install
snap install bower --classic
bower install
grunt

Se tudo estiver bem até aqui, podemos seguir.

Crie sua base de dados no influxdb:

influx
#será carregado o prompt do banco de dados, então digite:
create database nome_escolhido_por_voce
create user "usuario" with password "senha"
grant all on sensors to usuario
exit

Depois de criar a base de dados, lembre-se de seu nome, usuário e senha criados e adicione-os na bridge.py, que criaremos mais adiante.

Depois que estiver funcionando, se precisar depurar consultando a base de dados, faça:

influx
use sua_base_criada
show measurements

Não vou dispor o resultado dessa consulta agora, é apenas referência nesse momento.

Teste o mqtt2influxdb:

mqtt2influxdb -c /etc/hardwario/mqtt2influxdb.yml --test

E então:

npm install
npm install pm2 -g
pm2 start `which python3` --name "mqtt2influxdb" -- `which mqtt2influxdb` -c /etc/hardwario/mqtt2influxdb.yml
pm2 save

As coisas configuradas sem grandes explicações foram passos pelos quais passei. Cumprindo os requisitos, provavelmente você não passará pelos problemas que passei.

Bridge.py

O programa a seguir foi o que utilizei (com algumas mudanças, já que a base original do programa não fui eu quem criou, e algumas coisas eu faço de outro jeito). Chamei de bridge.py com o seguinte conteúdo:

#!/usr/bin/env python3
import paho.mqtt.client as mqtt
import datetime
import time
from influxdb import InfluxDBClient

def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))
    client.subscribe("/seu_topico/#")
    
def on_message(client, userdata, msg):
    print("Received a message on topic: " + msg.topic)
    # Use utc as timestamp
    receiveTime=datetime.datetime.utcnow()
    message=msg.payload.decode("utf-8")
    isfloatValue=False
    try:
        # Convert the string to a float so that it is stored as a number and not a string in the database
        val = float(message)
        isfloatValue=True
    except:
        print("Could not convert " + message + " to a float value")
        isfloatValue=False

    if isfloatValue:
        print(str(receiveTime) + ": " + msg.topic + " " + str(val))

        json_body = [
            {
                "measurement": msg.topic,
                "time": receiveTime,
                "fields": {
                    "value": val
                }
            }
        ]

        dbclient.write_points(json_body)
        print("Finished writing to InfluxDB")
        
# Set up a client for InfluxDB
dbclient = InfluxDBClient('127.0.0.1', 8086, 'usuario_influx', 'senha_influx', 'db_influx')

# Initialize the MQTT client that should connect to the Mosquitto broker
client = mqtt.Client("client_id_unico")
client.on_connect = on_connect
client.on_message = on_message
client.username_pw_set('usuario_mqtt','senha_mqtt')
connOK=False
while(connOK == False):
    try:
        client.connect("ip_do_servidor", 1883, 60)
        connOK = True
    except:
        connOK = False
    time.sleep(2)

# Blocking loop to the Mosquitto broker
client.loop_forever()

No diretório home do usuário no servidor, criei o diretório bin. Dentro dele coloquei esse programa Python (certamente alguns de vocês ficarão bravos pelos setups extras, mas relevem). Depois, transforme esse programa em executável e rode-o manualmente:

#lembre-se de que estamos como root. Supondo o usuário /home/dobitaobyte:
mkdir /home/dobitaobyte/bin
mv bridge.py /home/dobitaobyte/bin
cd /home/dobitaobyte/bin
chmod 750 bridge.py
./bridge.py

Faça um teste publicando alguma coisa a partir do Raspberry. Nesse artigo tem um exemplo para teste. Tendo funcionado (com código de retorno 0), pode parar o programa com Ctrl+C e crie o serviço de sistema. Edite o arquivo /etc/systemd/system/mqtt2influx.service e adicione o seguinte conteúdo:

[Unit]
Description=From Mosquitto to Influxdb
After=network.target

[Service]
Type=simple
ExecStart=/home/dobitaobyte/bin/bridge.py
RemainAfterExit=true
StandardOutput=journal
User=root

[Install]
WantedBy=multi-user.target

Salve o arquivo e habilite o serviço:

systemctl enable mqtt2influx

Habilite também o Grafana:

systemctl enable grafana-server

No Linux não precisamos reiniciar o sistema, exceto tenha havido uma atualização do initrd (initramfs atualmente) ou uma atualização do kernel. Mas para não ter que escrever todos os serviços que reiniciei para checagem e validação, vou recomendar um reboot do servidor:

shutdown -r now

Configurar o Grafana

Depois de reiniciado, já deve ser possível acessar o Grafana pelo browser, na porta 3000. O usuário e senha padrão é admin/admin, que deverá ser trocado ao primeiro login.

datasource

Ao acessar, o primeiro passo é criar o data source – em nosso caso, o InfluxDB.

grafana e MQTT - datasource

A criação do datasource estará bem diante de seus olhos ao fazer o login. Só deixe como nessa imagem acima, colocando os dados relativos, como: nome de banco, usuário, senha e URL.

O próximo passo é criar um dashboard. Essa é a parte que vou mostrar como criar o alerta, mas não vou entrar nos detalhes das formas de configurar cada um dos widgets disponíveis porque tem um monte de conceitos. Vou apenas mostrar o processo de criação do bot Telegram e como utilizá-lo no Grafana.

Dashboard

Crie um novo dashboard e adicione um painel. No caso, estou exemplificando com um painel de gráfico; não são todos os widgets que possuem o campo Alert.

O que teremos abaixo do gráfico vazio é o local da query ao influxdb. Conforme a bridge for alimentando o banco de dados, os tópicos aparecerão no segundo campo de FROM ao clicar sobre ele.

grafana e MQTT - dashboard

Logo acima da query no canto esquerdo, devemos escolher o datasource.

Em FROM especifico apenas o tópico.

Em SELECT troquei o campo mean() por distinct. Nessa query dá pra fazer absurdos, é quase uma inteligência artificial o que se pode obter de resultados, mas não é minha praia, portanto fiz o básico, que já é funcional.

Em seguida, podemos configurar o alarme, desde que já tenhamos configurado o nosso “fofoqueiro”. Chamei de “Guardian”. Vamos ver como configurar o alarme no gráfico e em seguida veremos como criar esse bot Telegram para enviar o alarme.

grafana e MQTT - alert

Nessa parte definimos um nome, tempo de avaliação e tempo de retenção. A checagem está para cada 1 minuto, com retenção de 5 minutos antes de enviar um alarme.

Nas condições, pego o último valor da query A (cada query criada recebe uma letra, como pode-se reparar na segunda imagem acima) e defino o threshold, que no caso é quando estiver ACIMA do valor 130.

Em Notificações, selecionei o Guardian e em mensagem coloquei um texto a enviar.

Sempre que fizer uma alteração, clique em Save e em seguida, Apply.

Repare na imagem de destaque do artigo que criei um gráfico constante chamado Proteção do SD. Esse gráfico só muda de 1 para 0, que é quando o sistema de arquivos do Raspberry sai do modo protegido para o modo desprotegido. Para aumentar a vida útil do micro SD do seu Raspberry, siga esse tutorial.

Quando queremos instalar um programa no Raspberry, precisamos desproteger o micro SD, mas já percebi que é comum esquecer de reiniciá-lo para que volte para o modo protegido, por isso criei um alarme para esse caso, no qual seremos lembrados pelo Grafana e MQTT.

Notificações no Grafana

Agora vamos ver como se configura uma notificação no Grafana. No caso, vamos utilizar o Telegram Bot, exemplificado nesse outro artigo.

Para criar o notificador, clique no sininho da coluna à esquerda da tela do Grafana e vá ao último item.

grafana e MQTT - notifications

Depois clique em New Channel. Escolha a opção Telegram na caixa de seleção. Agora precisamos de 2 itens fundamentais; o token e o chat ID. Para isso, precisamos primeiro criar o bot.

grafana e MQTT - telegram

Criando o chat bot Telegram para usar com Grafana e MQTT

Primeiramente, crie um grupo de chat no Telegram. Pode ser pelo celular ou pelo aplicativo desktop. Adicione as pessoas que deverão receber notificações e inclua seu bot. Mais uma vez, para que eu não tenha que descrever o processo de criação do bot nesse artigo, leia esse tutorial que escrevi. Apenas crie o bot.

Quando o bot for criado, ele já poderá ser incluído no grupo de chat normalmente, mas para configurá-lo no Grafana precisamos do chat-id. Para isso acesse a URL:

https://api.telegram.org/botTOKEN_DO_SEU_BOT/getUpdates

Troque TOKEN_DO_SEU_BOT pelo token de verdade e mantenha o prefixo bot como está na URL. Essa consulta retornará uma resposta json bem grande, mas só nos interessa a chave chat, que contém “id”:-1234…., onde o número é um valor negativo de vários Bytes.

Pegue o valor do ID e preencha os campos do Telegram API Settings. Não vou colocar os valores aqui por motivos óbvios, mas a tela é essa:

grafana e MQTT - telegram API

Tendo preenchido os campos, será possível fazer um teste e, estando tudo certo, basta salvar. Para utilizar, já descrevi o processo mais acima.

O alerta de teste de proteção do SD ficou assim:

telegram alert in chat bot

Agora que acabamos o setup do Grafana e MQTT, vamos fazer o publisher no Raspberry.

MQTT publisher no Raspberry

Depois de toda essa configuração, hora de fazermos um serviço MQTT permanente no Raspberry, hum? Lembre-se de que o Raspberry aqui será um client publicando suas informações no broker MQTT. Siga esse tutorial para fazer as publicações por linha de comando e em seguida crie esse script shell para torná-lo um serviço de sistema:

#!/bin/bash
#Grafana e MQTT
CLIENT_ID=`hostname -s`
USERNAME='usuario_mqtt'
PASSWD='senha_mqtt'
BROKER='ip_do_broker'
ANSWER="NO"
PUBLISH_INTERVAL=5 #em segundos
FS_STATUS_RO=('NAO' 'SIM')
INTERVAL_TO_NEXT=60 # 1x por minuto

#DEPENDENCIAS
DIG=`which dig|wc -c`
MQTT=`which mosquitto_sub|wc -c`
[ $DIG -lt 3 -o $MQTT -lt 10 ] && {
    echo "Installing dnsutils tools package..."
    sudo mount -o remount,rw /
    sudo apt-get update
    sudo apt-get install -y dnsutils
    sudo apt-get install -i mosquitto mosquitto-clients
}

BC=`which bc|wc -c`
[ $BC -lt 3 ] && {
    echo "Installing bash calculator package..."
    sudo mount -o remount,rw /
    sudo apt-get update
    sudo apt-get install -y bc
}


publisher(){
        #faz o envio da informacao $2 para o topico $1
        mosquitto_pub -h $BROKER -u $USERNAME -P $PASSWD -t $1 -m $2 -i $CLIENT_ID
}


getValues(){
    echo ""
    echo "Starting a new cycle:"
    
    #uptime
    UPTIME_NOW=`uptime|cut -f1 -d,`
    publisher "/status/$CLIENT_ID/uptime" $UPTIME_NOW
    #MEMORIA - /status/$CLIENT_ID/memory/{used,free,shared,cache,available}
    #USADO    LIVRE    COMPARTILHADO    CACHE    DISPONIVEL
    echo -n "Sending memory usage..."
    MEM=(`free -m|head -n2|tail -n1|awk '{print $3" "$4" "$5" "$6" "$7}'`)
    #echo ${MEM[0]} #primeiro item
    publisher "/status/$CLIENT_ID/memory/used" ${MEM[0]}
    sleep 0.25
    publisher "/status/$CLIENT_ID/memory/free" ${MEM[1]}
    sleep 0.25
    publisher "/status/$CLIENT_ID/memory/shared" ${MEM[2]}
    sleep 0.25
    publisher "/status/$CLIENT_ID/memory/cache" ${MEM[3]}
    sleep 0.25
    publisher "/status/$CLIENT_ID/memory/available" ${MEM[4]}
    sleep 0.25
    echo -e "\t\t[OK]"
    
    #CACHE RAMFS - /status/$CLIENT_ID/ramfs
    echo -n "Sending RAMFS usage..."
    [ -d /dev/shm/inradio-cache/Default ] && {
        CACHE_RAMFS=`du -sh /dev/shm/inradio-cache/Default/|cut -f1|tr -d [[:alpha:]]|sed -re 's/,/\./g'`
        publisher "/status/$CLIENT_ID/ramfs" $CACHE_RAMFS
        sleep 0.25
        echo -e "\t\t[OK]"
    } || echo -e "[CHROMIUM BLOCKED?]"
    
    #FS READ-ONLY? - /status/$CLIENT_ID/fs/protected (0 para NAO)
    echo -n "Sending if FS is protected..."
    FS_IS_RO=`mount|grep mmcblk0p2|egrep '/dev/mmcblk0p2 on / type ext4'|egrep 'ro'|wc -c`
    [ $FS_IS_RO -gt 0 ] && FS_IS_RO=1
    publisher "/status/$CLIENT_ID/fs/protected" $FS_IS_RO #${FS_STATUS_RO[$FS_IS_RO]}
    sleep 0.25
    echo -e "\t[OK]"
    
    #USO DO SD: USADO / DISPONIVEL - usar ${DF_SD[0]} para primeiro item - /status/fs/{used,available}
    #VALOR EM MEGA
    DF_SD=(`df -h|egrep -i '/dev/root' |awk '{print $3" "$4}'|sed -re 's/,/\./g; s/G/00/g; s/M//g'`)
    [ `echo $DF_SD|wc -c` -lt 2 ] && DF_SD=(0 0) 
    echo -n "Sending free space..."
    publisher "/status/$CLIENT_ID/fs/used" ${DF_SD[0]}
    sleep 0.25
    publisher "/status/$CLIENT_ID/fs/available" ${DF_SD[1]}
    sleep 0.25
    echo -e "\t\t[OK]"
    
    #CPU - /status/loadavg
    echo -n "Sending CPU..."
    AVG=`cat /proc/loadavg |awk '{print $1}'`
    AVG=`echo $AVG*100|bc`
    publisher "/status/$CLIENT_ID/loadavg" $AVG
    sleep 0.25
    echo -e "\t\t\t[OK]"
    
    #Resolucao de video - /status/CLIENT_ID/video/resolution
    echo -n "Sending video resolution..."
    #... ou, cat /sys/class/graphics/fb0/virtual_size
    VIDEO_RES=`fbset -s |egrep '^mode'|cut -f2 -d\"`
    publisher "/status/$CLIENT_ID/video/resolution" "$VIDEO_RES"
    sleep 0.25
    echo -e "\t[OK]"
    
    #memoria de video - /status/CLIENT_ID/video/memory
    echo -n "Sending video memory..."
    VIDEO_MEM=`egrep gpu_mem /boot/config.txt |cut -f2 -d=`
    SIZE_OF=`echo $VIDEO_MEM| wc -c`
    [ $SIZE_OF -lt 2 ] && VIDEO_MEM='76'
    #VIDEO_MEM="${VIDEO_MEM}M"
    publisher "/status/$CLIENT_ID/video/memory" $VIDEO_MEM
    sleep 0.25
    echo -e "\t\t[OK]"
    
    
    #------------------------------ NETWORK -------------------------------------
    #eth0 / wlan0 - usando wlan no teste - /status/CLIENT_ID/network/eth0/{rx,tx,collisions}
    echo "Sending iface stats:"
    IFACE_ETH0=`ifconfig eth0`
    RX_BYTES=`echo $IFACE_ETH0|sed -re 's/.*(RX packets [0-9]+ bytes [0-9]+ ).*/\1/'|awk '{print $NF}'`
    TX_BYTES=`echo $IFACE_ETH0|sed -re 's/.*(TX packets [0-9]+ bytes [0-9]+ ).*/\1/'|awk '{print $NF}'`
    COLLISIONS=`echo $IFACE_ETH0|sed -re 's/.*(TX errors [0-9]+ dropped [0-9]+ overruns [0-9]+ carrier [0-9]+ collisions [0-9]+).*/\1/'|awk '{print $NF}'`
    IPADDR=`echo $IFACE_ETH0|sed -re 's/.*inet (([0-9]+.?){,4} )netmask.*/\1/'|egrep -v [[:alpha:]]`
    IP_LEN=`echo $IPADDR|wc -c`
    [ $IP_LEN -lt 3 ] && {
        IPADDR='NO_IP'
    }
    
    #PUB_IP=`dig +short myip.opendns.com @resolver1.opendns.com`
    PUB_IP=`wget -qO- http://ipecho.net/plain`
    #PUB_IP=`curl ifconfig.me`
    
    echo -n "* Public IP..."
    publisher "/status/$CLIENT_ID/network/eth0/publicip" $PUB_IP
    sleep 0.25
    echo -e "\t\t\t[OK]"
    
    echo -n "* Local IP on eth0..."
    publisher "/status/$CLIENT_ID/network/eth0/localip" $IPADDR
    sleep 0.25
    echo -e "\t\t[OK]"
    
    echo -n "* Received Bytes on eth0..."
    publisher "/status/$CLIENT_ID/network/eth0/rx" $RX_BYTES
    sleep 0.25
    echo -e "\t[OK]"
    
    echo -n "* Transmitted Bytes on eth0..."
    publisher "/status/$CLIENT_ID/network/eth0/tx" $TX_BYTES
    sleep 0.25
    echo -e "\t[OK]"
    
    echo -n "* Collisions on eth0..."
    publisher "/status/$CLIENT_ID/network/eth0/collisions" $COLLISIONS
    sleep 0.25
    echo -e "\t\t[OK]"
    
    echo "::: Collection is done on eth0 :::"
    
    IFACE_WLAN0=`ifconfig wlan0`
    RX_BYTES=`echo $IFACE_WLAN0|sed -re 's/.*(RX packets [0-9]+ bytes [0-9]+ ).*/\1/'|awk '{print $NF}'`
    TX_BYTES=`echo $IFACE_WLAN0|sed -re 's/.*(TX packets [0-9]+ bytes [0-9]+ ).*/\1/'|awk '{print $NF}'`
    COLLISIONS=`echo $IFACE_WLAN0|sed -re 's/.*(TX errors [0-9]+ dropped [0-9]+ overruns [0-9]+ carrier [0-9]+ collisions [0-9]+).*/\1/'|awk '{print $NF}'`
    IPADDR=`echo $IFACE_WLAN0|sed -re 's/.*inet (([0-9]+.?){,4} )netmask.*/\1/'|egrep -v [[:alpha:]]`
    IP_LEN=`echo $IPADDR|wc -c`
    [ $IP_LEN -lt 3 ] && {
        IPADDR='NO_IP'
    }
    
    echo -n "* Local IP on wlan0..."
    publisher "/status/$CLIENT_ID/network/wlan0/localip" $IPADDR
    sleep 0.25
    echo -e "\t\t[OK]"
    
    echo -n "* Received Bytes on wlan0..."
    publisher "/status/$CLIENT_ID/network/wlan0/rx" $RX_BYTES
    sleep 0.25
    echo -e "\t[OK]"
    
    echo -n "* Transmitted Bytes on wlan0..."
    publisher "/status/$CLIENT_ID/network/wlan0/tx" $TX_BYTES
    sleep 0.25
    echo -e "\t[OK]"
    
    echo -n "* Collisions on wlan0..."
    publisher "/status/$CLIENT_ID/network/wlan0/collisions" $COLLISIONS
    sleep 0.25
    echo -e "\t[OK]"
    
    echo "::: Collection is done on wlan0 :::"
    
    echo ""
    echo "Done this time."
}


while [ true ]; do
   getValues
   sleep $INTERVAL_TO_NEXT
done

Dê permissão de execução para o script, coloque-o no home do usuário em um diretório chamado bin (só por estética) e crie o serviço:

chmod 750 MQTTpub.sh
mkdir -p /home/pi/bin
mv MQTTpub.sh /home/pi/bin

Como root, crie o arquivo de serviço do sistema em /etc/systemd/system/MQTTpub.service. Dentro dele, o seguinte conteúdo:

[Unit]
Description=MQTT subscribe service
After=network.target

[Service]
Type=simple
ExecStart=/home/pi/bin/MQTTpub.sh
RemainAfterExit=true
StandardOutput=journal
User=root

[Install]
WantedBy=multi-user.target

Agora para habilitar o serviço de sistema:

systemctl enable MQTTpub.service

Depois disso podemos iniciar, parar ou reiniciar o serviço assim:

service MQTTpub start

Pronto, agora é só desfrutar!

Comprar Raspberry

Se precisa comprar um Raspberry Pi 4, a MASUGUX tem por um ótimo preço. Na Saravati tem a Raspberry Pi 3B+, assim como na CurtoCircuito que tem a Raspberry Pi 3.

Tenho mais algumas novidades importantes para escrever, pelos próximos dias teremos novos e interessantes artigos. Até a próxima!

 

Revisão: Ricardo Amaral de Andrade

Djames Suhanko

Djames Suhanko é Perito Forense Digital. Já atuou com deployer em sistemas de missão critica em diversos países pelo mundão. Programador Shell, Python, C, C++ e Qt, tendo contato com embarcados ( ora profissionalmente, ora por lazer ) desde 2009.