Manual

do

Maker

.

com

IoT - Introdução e boas práticas com MQTT

IoT - Introdução e boas práticas com MQTT

Durante a escrita de um outro post sobre IoT, decidi interrompê-lo para fazer este post aqui. Sei que muitos gostam de mão-na-massa, mas estamos em plena expansão da Internet das coisas e certamente muitos problemas relacionados surgirão, desde estrutural à problemas de segurança. Vamos então ver agora um apanhando de conceitos e juntar o melhor de cada implementação.

Os meus posts são todos baseados em Mosquitto, mas é notória a atuação do HiveMQ na IoT. Não há tanta diferença entre eles, mas o negativo em haver diferenças é a falta de uma padronização forte. Assim, cada um implementa o protocolo à sua maneira e divisões vão surgindo. Se continuar assim, chegará um ponto que será difícil migrar de uma estrutura para outra. Aqui procurarei ater-me ao Mosquitto e sempre que possível farei referências à outra implementação (ou outras).

Se você não tem ainda nenhum conceito a respeito, permita-me fazer uma breve introdução.

Breve Introdução

MQTT - ou - Message Queuing Telemetry Transport. Trata-se de um protocolo leve de publicação e subescrição de mensagens, utilizado fundamentalmente na Internet of Things. O MQTT é o protocolo ideal para gerenciamento e interação entre dispositivos de baixo poder de processamento e memória. Também conhecido como o protocolo IoT M2M (machine-to-machine).

Você encontra um documento de tamanho assustador da padronização 3.1.1 OASIS em aqui.

Sobre a implementação MQTT com Mosquitto, aqui.

Também sobre HiveMQ, todos implementados sob a última versão de 2014 até o momento desse post.

Existem implementações próprias, como no caso da Axiros, que tem sua implementação MQTT na pilha TR-069, com um produto chamado AX.ACT.

Existem outros protocolos de interação com dispositivos remotos, mas tratam-se de outros tipos de dispositivo, principalmente relacionados à estruturas de rede - mas não somente. Um bom exemplo é o dos cable modems, que utilizam o protocolo DOCSIS para gerenciamento e informe. Já para dispositivos que usam (por exemplo) xDSL, existe o protocolo TR-069. Esse tem uma longa história e uma vasta implementação que acabou gerando outros TR's ao longo dos anos devido às evoluções tecnológicas. Porém, nenhum desses protocolos servem para gerenciamento de dispositivos como microcontroladoras e até alguns dispositivos com sistema operacional, não só pelo poder de processamento, mas também pelo tamanho da pilha do protocolo.  Mas não foi por isso que surgiu o MQTT - se esperava por isso, sinto muito.

Não quero influenciá-lo com minha opinião pessoal, mas particularmente acho que o protocolo surgiu no melhor dos momentos. Criado pela Cirrus em 1999, o protocolo tornou-se atualmente o padrão dos dispositivos IoT. O protocolo é tão leve que qualquer cabeçalho TCP/IP é maior do que a mensagem carregada no pacote!

Atualmente o protocolo pode ser trafegado sob SSL, suporta usuário e senha e você pode implementar outras camadas de autenticação se desejar. Mas uma implementação ruim poderá colocar toda a estrutura em risco; senhas ruins são comumente utilizadas por usuários domésticos e aí que mora o perigo. Por isso, mais uma vez com minha opinião pessoal, um conjunto de segurança deverá ser devidamente implementado para reduzir riscos e entre esses protocolos, certamente reconhecimento biométrico pode ser uma opção aceitável e cômoda para o usuário final. Sigamos.

PubSub

A comunicação e extremamente simples e os dispositivos não conversam com os clientes diretamente. A comunicação se dá através de um intermediário; um server que tem o serviço de interação denominado Broker. O broker recebe a informação de ambos os lados, dispositivos e clients. Essas mensagens são dividas em duas condições específicas.

Publish

A publicação trata do envio de determinada informação, seja ela qual for. Quando uma mensagem precisa ser enviada, ela é feita através do método Publish.

Subscribe

Quando um client ou dispositivo precisa receber algum tipo de informação, seja qual for, ele deve se inscrever a um tópico e a partir de então passa a receber informação sobre ele.

Tópicos para controle por MQTT

Essa parte é quase mágica; não é necessário configurar um tópico, basta publicá-lo,  em conformidade com a documentação do Mosquitto. O broker, que atua como um intermediário passivo (isto é, ele não faz gerenciamento dos dispositivos, apenas transporta a comunicação), pode fazer a persistência dos dados se necessário. Essa persistência pode ser feita em base de dados, em arquivo ou no caso da implementação doméstica que estou fazendo, em sistem de arquivos na memória (RAMFS).

O protocolo não é utilizado somente para abrir portas, janelas, informar temperturas, ligar luzes e demais tarefas domésticas - o protocolo é muito útil também para o gerenciamento de hardware, podendo servir como alternativa ao SNMP com a liberdade de implementação leve somente daquilo que for necessário.

Nos artigos anteriores sobre MQTT mantive o tópico "casa/" propositalmente, para iniciarmos a implementação nesse ponto, portanto, vamos pensar a respeito.

Temos o tópico raiz chamado casa. O segundo nível pode ser os comodos e dentro dos cômodos temos as lâmpadas.

Você pode se inscrever utilizando coringas, mas não pode publicar como abaixo:

casa/+/status/lampada

Isso seria a intenção de se cadastrar em todos os cômodos da casa para receber status de lâmpadas, mas você não pode fazer isso para publicar, por exemplo, para acender todas as lâmpadas da casa ao mesmo tempo. Um contorno para isso seria um tópico comum para os dispositivos. Um tópico como:

casa/geral/lampadas

Todos os dispositivos subescritos para esse tópico acenderão a lâmpada conforme seu status. Vamos falar de wild cards, já que foi utilizado.

Wild cards

Esses coringas não são tão especiais, mas ajudam em diversos aspectos.

Single Level

É o sinal de +, como explicado mais acima. Invés de dar o nome de um cômodo da casa, o tópico se cadastrou em todos os sub-tópicos de "casa/".

Multi Level

No caso, a cerquilha (#),

Repare que até agora falamos apenas dos tópicos no broker, mas para o usuário é necessário uma interface que abstraia essa parte técnica; ele quer clicar em um menu de comodos e escolher a lâmpada da sala apenas clicando. O status deve ser automaticamente publicado pela MCU e a interface com o usuário deve exibir o status escrito ou melhor, um ícone de uma lâmpada acesa. Vamos passar por todos esses niveis até termos a aplicação do usuário, mas não caberá tudo em 1 único post. Aliás, haverá mais alguns posts até que o controle total da casa seja concluido.

Devido a inexistência de uma padronização forte, infelizmente temos algumas variações. Não encontrei nenhuma citação no Mosquitto, mas no HiveMQ tem mais um caracter especial que é o "$", utilizado para estatisticas internas do broker - Mais uma vez - no HiveMQ.

Quality of Service

O MQTT define 3 níveis de QoS, relacionado ao esforço dedicado para garantir a entrega da mensagem. Estão disponíveis 3 níveis de QoS e as mensagens podem ser enviadas em qualquer nível de prioridade, sendo que o nível final é definido pelo client. Isto é, se um Arduino definir a entrega em 2 e o client em 0, a prioridade é do client.

Níveis

0 - Comunicação ocorre apenas uma vez, sem confirmação de entrega.

1 - No mínimo 1 envio com confirmação requerida.

2 - Uma entrega usando um handshake de 4 passos. Isso ocorre em nível de protocolo, portanto eu mostrarei isso em video em algum momento.

Retenção de mensagem

Isso significa que o broker pode enfileirar as mensagens para fazer um tipo de broadcast para todos os subescritores de uma só vez.

Mais aconselhamentos

Estruture corretamente os tópicos

Se você reparar em meus tópicos, em um eu utilizei "/mcu" e no outro utilizei "casa/". O tópico é o nome e subtópicos são separados por barra. Não faz sentido iniciar com "/", mas como você pode ver nos exemplos anteriores, funciona. Se pensar na condição de árvore de sistema (não é esse o conceito), pode facilitar para os "shelleiros", mas usando-o assim é um sinal de que o conceito não está amadurecido em sua cabeça ou o conceito está sim bem amadurecido em sua cabeça dura.

Evite utilizar espaços nos nomes de tópicos

Você pode usar espaços nos nomes de tópicos, eu não vejo problemas em fazer parsing disso, mas em "best pratices" da documentação do HiveMQ é explicitamente recomendado que não se utilize espaços em nomes de tópicos. Se petende manter compatibilidade, acredito que seja um bom conselho a seguir.

Medite sobre o nome do tópico

Ele deve ser conciso, claro, objetivo. Isso evita enganos nas subescrições, ainda mais se sua implementação depender de mão de obra alheia posteriormente.

Use somente ASCII

Se você é programador, provavelmente sabe de que se trata. É o unsigned char, ou, os caracteres não acentuados, encontrados na tabela ASCII.

Eu recomendo fortemente que sequer sejam utilizados símbolos.

Identificador único para clientID

Se você tiver nomes repetidos ou não claros, certamente você não identificará o dispositivo adequadamente, o que pode ser um problema no gerenciamento.

Evite inscrever-se em #

Exceto tenha uma razão clara para isso, subescrever-se para todos os tópicos de uma raiz vai gerar um throughput alto dependendo do número de clientes conectados. Estou citando isso pensando em Broker como serviço, para o caso de você ser um provedor.

 Use tópicos específicos

Quanto mais clara for a raiz, mais fácil será seu gerenciamento. A estrutura criada como exemplo mais acima fala por si só.

 Segurança

A única exceção para não utilizar SSL no canal de comunicação é se você estiver fazendo um laboratório. Usuário e senha não são obrigatórios, mas é totalmente desaconselhável fazê-lo dessa maneira. E ainda que esteja utilizando usuário e senha, qualquer sniffer conseguirá capturá-los imediatamente no tráfego de rede, portanto, use sempre em conjunção SSL, usuário e senha.

O ruim de deixar o usuário escolher a senha de comunicação com o broker é a questão da obviedade. Ele vai colocar 'josé' e '1234'. É bom poder gerar uma senha segura e mantê-la no dispositivo que interagirá com o broker, porque se o José estiver abrindo a porta de casa pelo celular, o vizinho 'hacker' dele também está.

Quanto de hardware é necessário para fazer um broker?

Essa resposta depende do número de clientes e tópicos. Em casa estou utilizando um Raspberry Pi 2 como broker, DNS, NTP e cobaia de laboratório e não há consumo significativo.

Que dispositivos posso conectar ao broker?

Todos que suportem alguma implementação do protocolo MQTT. Inclusos estão os Arduinos (todos), diversos modelos de PIC e todas as arquiteturas microcontroladas e microprocessadas superiores, incluindo dispositivos ARM e MIPS.

Como posso implementar uma estrutura completa para testes?

Você pode iniciar suas experiências implementando o MQTT em um Arduino e conectando-o a um broker público, como o próprio mosquitto (link).

Se você deseja implementar tudo, desde a estaca zero, escrevi estes posts que lhe auxiliarão na implementação completa:

Configurando um broker

Conectr um ESP8266 ao broker (Lua)

Configuração OTA por MQTT (1 de 2)

Configuração OTA por MQTT (2 de 2)

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.