Manual

do

Maker

.

com

ESP8266 - Como configurar atualização OTA por MQTT (1 de 2)

ESP8266 - Como configurar atualização OTA por MQTT (1 de 2)

Atualização OTA por MQTT

Finalizando os posts sobre atualização via OTA, vamos ver agora como informar o dispositivo da IoT para ele buscar atualizações de firmware. Essa tarefa envolverá a configuração completinha do servidor, que atenderá diversos outros propósitos, como por exemplo, aproximar os dispositivos de um horário real sem que eles estejam utilizando NTP ou dependendo do dispositivo, por NTP. Para isso, configuraremos um Raspberry para ser o servidor da rede e ele rodará os seguintes serviços:

Domain Name Server

Ele será o servidor DNS para navegação web e para reconhecimentos dos hosts de sua rede local.

RAMFS - Ou, Sistema de Arquivos em memória

Vamos poupar o cartão micro-sd do Raspberry fazendo persistencia dos dados na memória RAM.

NTP - Network Time Protocol

O timestamp do Raspberry será certificado via NTP, o que o tornará preciso. Ele também será servidor de data/hora da rede local.

MQTT - Message Queue Telemetry Transport

O protocolo da Internet das coisas, criado pela Cirrus Link Solutions (link) em 1999. Toda a comunicação entre dispositivos na rede se dará através de um broker MQTT configurado no Raspberry, que atuará também como informante de data/hora para os dispositivos da rede que não tiverem suporte a NTP.

SSH - Secure SHell

O servidor ssh para conexões remotas ao Raspberry através de um computador da rede local. Desse modo não será necessário fucar conectado ao RPi diretamente.

/var/log/messages

Reabilitaremos o arquivo de logs messages para armazenar os eventos gerados pelo sistema de maneira tradicional.

Para finalizar, gostaria de deixar claro que essas configurações se aplicam a qualquer Linux, seja em Embedded, desktop, notebook, servidores ou outra coisa que rode Linux - mas no caso do Raspbian, ele já usa o messages por padrão. Especificamente nesse caso estou utilizando Raspberry porque ele é meu concentrador doméstico e esse post servirá como adendo a um próximo artigo em que iniciarei automação doméstica.

Primeiro passo - Configurar adequadamente o Raspberry

O Raspberry fará muitos serviços na rede e seu papel é essencial. Portanto, devemos dar uma atenção especial a ele e posteriormente nos ateremos aos tópicos ainda não citados.

Mosquitto

O servidor (ou 'Broker') utilizado para a comunicação MQTT se chama Mosquitto. Existem outras implementações, mas essa é nativa no Linux, bastando instalá-la. Não vou reescrever a configuração do serviço porque escrevi um post dedicado a isso, então, antes de seguir a leitura (exceto a leitura tenha apenas propósito informativo), obrigatoriamente você deve ler esse post ao menos até o ponto em que a configuração do broker é finalizada. Porém, invés de instalar o Mosquitto diretamente do repositório que existe por padrão, faça desse modo:

wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key
sudo apt-key add mosquitto-repo.gpg.key
cd /etc/apt/sources.list.d/
sudo wget http://repo.mosquitto.org/debian/mosquitto-wheezy.list
sudo apt-get update
sudo apt-get install mosquitto

Só pra um "duplo-confere", vou deixar minha conf abaixo. Mas essa não é a única configuração do broker, leia o artigo supracitado.

Eu utilizei o recurso do include em /etc/mosquitto/conf.d, criando nesse diretório o arquivo local.conf com o seguinte conteúdo:

persistence true
persistence_file mosquitto.db
persistence_location /mnt/RAM/mosquitto_db

log_dest syslog
log_dest topic
log_dest stderr
log_type error
log_type warning
log_type notice
log_type information
log_type debug
log_timestamp true

password_file /etc/mosquitto/bb.pw
acl_file /etc/mosquitto/bb.acl

No arquivo mosquitto.conf apeas comentei as linhas referente à persistência.

Os arquivos bb.* que criei dentro de /etc/mosquitto/ receberam as permissões 644.

Se não sabe como se mudam as permissões, simplesmente digite isso:

chmod 644 /etc/mosquitto/*.{acl,pw}

Mas não deixe de aprender como funciona o sistema de permissões no Linux. Terminando a configuração do broker, siga da próxima linha.

RAMFS

A RAMFS é um sistema de arquivos em memória, nesse caso específico ela será muito útil, pois evitará I/O no cartão micro-sd, aumentando assim sua vida útil.

No arquivo mosquitto.conf você escolheu um arquivo de persistência e esse arquivo aponta para um diretório. Eu gosto de deixar notória a utilização do RAMFS, portanto sugiro que somente essa linha seja modificada na configuração que você deve ter feito anteriormente no mosquitto.conf. Troque o caminho do arquivo de persistência para /media/ramfs/mosquitto e monte aí a RAMFS. Para fazê-lo, leia agora esse outro post onde relato o processo (muito, muito simples). Após configurada essa parte, volte a leitura e siga da próxima linha.

DNS

Não é obrigatório, mas tratando-se de IoT, nada mais justo que seus dispositivos serem reconhecidos na rede por nomes familiares, certo? Afinal, a Internet das coisas é para as pessoas comuns e pessoas comuns não ficam decorando endereços IP. De bônus, seu servidor DNS resolverá nome para a Internet e o que uma vez for reconhecido por ele, tornará a resolução de nome tão mais rápido que acelerará sua navegação no que se refere a esse primeiro estado.

Para configurar o DNS, escrevi esse post de forma bastante clara. Não é uma configuração complexa, mas não é tão rápida como trocar o papel de parede. Após terminar essa configuração (e sugiro fortemente que o faça), volte e siga da próxima linha.

SSH

Não é nada prático ficar na frente do Rapberry configurando-o como se fosse um desktop. Eu prefiro fazer o acesso remoto e no conforto dos meus 2 monitores extendidos, fazer a configuração tranquilamente. Para que você possa fazê-lo, simplesmente instale o servidor de acesso remoto SSH. Se você não conhece, trata-se de um serviço de acesso remoto por console criptografado, que lhe permite inclusive abrir aplicação gráfica remota sem que ela esteja configurada ou instalada em seu sistema nativo. Pode parecer até absurdo, mas todas as chamadas binárias são feitas na origem da chamada, portanto, apesar do Raspberry ser ARM e seu notebook/desktop ser x86, você pode abrir a aplicação gráfica do Raspberry sem problemas. Para isso o acesso ssh deve ser feito com o parâmetro '-X', depois basta chamar o binário do programa gráfico pelo console. Pode testar com o xpdf se não souber o nome de mais nenhum. Mas claro, primeiramente você deve instalar o servidor ssh. Para tal, de forma tão mais simples do que ler esse parágrafo enorme, faça:

sudo apt-get install openssh-server

Tente uma conexão local para ver se o serviço está rodando e não tem nenhum problema. No meu caso, o Raspberry é meu DNS primário e eu o chamo de 'ns1'. O usuário padrão foi mantido tendo apenas a senha trocada. Se você seguiu direitinho as dicas na ordem que estou explicando, nesse ponto você conseguirá testar a conexão ssh assim:

ssh pi@ns1

Delicia de comando curto para fazer uma conexão remota, não? É, eu sei. Você está fazendo local para testar, mas quando fizer remota (que poderá ser a partir do próximo passo) será tão simples quanto, bastando incluir a flag '-X' se desejar acessar os programas gráficos do Raspberry Pi (isso não inclui o desktop LXDE).

Configurar NTP Server em Linux

Vamos configurar ambos; o Network Time Protocol Server e Client. Isso porque alguns dispositivos da IoT tem a habilidade de consultar um servidor de hora, e nada mais elegante do que ter seu próprio serviço na rede, certo? Mas claro, ele próprio precisa estar devidamente configurado. Iniciando pelo server então.

sudo apt-get install ntp ntpdate

Edite o arquivo /etc/ntp.confe inclua uma linha restrigindo as consultas à sua rede local. A linha deve ficar desse modo:

restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap

O servidor tem que estar hábil a fazer broadcast do tempo. Uma linha com o broadcast e sua rede deve ser inserida:

broadcast 192.168.1.255

Não quero entrar em conceitos de rede, mas apenas para tentar deixar um pouco mais claro citarei que os IPs exemplificados pertencem à minha rede. A rede utilizada é classe C com a máscara padrão (255.255.255.0), o que significa que posso ter até 254 hosts na minha rede (porque 0 é a reserva de rede e 255 é o broadcast). Se você está rodando a rede padrão de seu roteador, certamente será uma classe C também. E muito provavelmente os primeiros 2 octetos serão 192.168. Chega de falar de rede, o que quero dizer aqui é que se sua rede for classe B (por exemplo, 172.16.0.0), se broadcast será 172.16.255.255, mas isso significa 16²-1, nenhuma rede local jamais terá isso, ainda que até o giz de cera da sua filha esteja na IoT.

Se ainda não fui capaz de exclarecê-lo, pegue seu broadcast com o comando 'ifconfig'. No resultado você encontra o broadcast:

Configuração de um servidor de hora local, caso o NTP se torne inacessível via Internet. Eu fiz isso:

server  127.127.1.0 # local clock
fudge   127.127.1.0 stratum 10

O stractum é baseado na distância. Anyway, se ficar sem internet, não terá e onde pegar precisão.

Coloque também uma linha de log, preferenciamente após o driftfile para manter as coisas organizadas:

logfile /var/log/ntp.log

Todos os demais parâmetros necessários e essenciais já vem configurados por padrão. Nesse momento você já pode iniciar o NTP server:

sudo service ntpd start

Configurar o NTP Client para sincronizar com seu NTP Server

Os clientes da rede (sendo esses computadores com sistemas operacionais instalados) deverão utilizar-se do mesmo serviço NTP, mas dessa vez a diferença no arquivo de configuração consiste em modificar apenas as entradas relacionadas aos servidores de hora a serem consultados. Se seus dispositivos tiverem alguma biblioteca para ajuste de hora por NTP, ainda que não contenham sistema operacional, a configuração se dará por outro modo. O próprio Arduino tem uma biblioteca NTP Client, vamos configurar o NTP Client no ESP8266 de outra maneira. Mas continuando no modelo de configuração Client para dispositivos que contenham sistema operacional, você deverá apontar os servers nas linhas onde está desse modo (no caso do Emdebian):

server 0.debian.pool.ntp.org iburst
server 1.debian.pool.ntp.org iburst
server 2.debian.pool.ntp.org iburst
server 3.debian.pool.ntp.org iburst

Troque (ou adicione) a primeira linha (no meu caso, esse é meu NTP):

server 192.168.1.2 prefer

Isso significa que o seu servidor é o primeiro e o preferido na busca de data/hora. Nesse ponto você já pode iniciar o client:

service ntp start

Você pode também ver o status agora, utilizando o comando:

ntpq -p

Agora você já pode configurar o horário local, mas não manualmente. Isso deve ser feito através do comando:

ntpdate -u 192.168.1.2

Que buscará data/hora em seu servidor. Eu fiz meu próprio servidor fornecer-se a hora. Claro, ele consultou fora e depois aplicou a si mesmo, o comando ficará travado por um tempinho. Depois fiz uma consulta mais elaborada do status.

E agora você está pronto para servir e confiar na hora dos dispositivos de sua rede!

Reabilitar o arquivo de logs padrão do sistema (/var/log/messages)

Nesse caso, recomendo a leitura desse meu post no Sistemas Embarcados. Como citei lá em cima, o Raspbian ainda usa o messages por padrão. Caso esteja usando-o, pule essa parte.

Essa é a parte de configuração do servidor. Na próxima já colocaremos o ESP8266 para conversar com o broker; criaremos alguns tópicos e veremos o processo de atualização OTA informado através do MQTT.

Inscreva-se no nosso canal Manual do Maker Brasil no YouTube.

Próximo post a caminho!

Nome do Autor

Djames Suhanko

Autor do blog "Do bit Ao Byte / Manual do Maker".

Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.