Manual
do
Maker
.
com
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.
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.
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.
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.
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.
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.
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.
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.
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ó.
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á.
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.
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.
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:
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!
Autor do blog "Do bit Ao Byte / Manual do Maker".
Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.