Pular para o conteúdo

MQTT: a placa e o resto do mundo

Publicar, assinar, curingas e o testamento — como o painel descobre que o sensor caiu.

Um sensor ligado por cabo fala com um computador. Vinte sensores espalhados numa casa falam com um broker, e quem quiser ouve. MQTT é esse protocolo: Arcane.IoT traz um cliente 3.1.1 falado à mão sobre TCP, sem dependência.

precisa de broker
adopt Arcane.IoT as IoT

// precisa de um broker: docker run -p 1883:1883 eclipse-mosquitto
c := IoT.mqtt("localhost", 1883, "sala")
c.publicar("casa/sala/temperatura", "21.5")
c.assinar("casa/+/temperatura", lambda m: out $"{m["topico"]}: {m["mensagem"]}")
sleep(500)
c.fechar()

Os curingas, e onde cada um vale#

FiltroCasaNão casa
casa/sala/luzcasa/sala/luzqualquer outro
casa/+/luzcasa/sala/luz, casa/quarto/luzcasa/sala/piso/luz
casa/#casa/sala/piso/luzjardim/luz

+ casa um nível; # casa o resto, e só no fim do filtro. Publicar num curinga é recusado — eles são de assinatura, e publicar("casa/+/luz") criaria um tópico literalmente chamado +.

O testamento: como se descobre que o sensor caiu#

Um sensor sem energia não avisa ninguém: ele simplesmente para de publicar, e o painel fica com o último valor congelado na tela — parecendo atual. O last will é uma mensagem que o broker publica quando a conexão cai:

precisa de broker
adopt Arcane.IoT as IoT

c := IoT.mqtt("localhost", 1883, "estufa", "", "", 60, {
    "topico": "casa/estufa/estado",
    "mensagem": "offline",
    "reter": yes})
c.publicar("casa/estufa/estado", "online", 0, yes)
c.fechar()

Com reter := yes, quem assinar depois recebe o último valor na hora — é o que faz um painel recém-aberto já mostrar o estado em vez de esperar a próxima leitura.

QoS: 0 e 1#

QoSPromessaQuando
0manda e esqueceleitura periódica — a próxima chega em 5 s de qualquer forma
1chega pelo menos uma vez (espera o PUBACK)um comando: "desligar a bomba"

Não há QoS 2 aqui, e a razão está escrita: ele exige guardar o estado de quatro mensagens por publicação, e quase nenhum projeto de sensor usa. Com QoS 1, o receptor precisa aguentar repetição — um comando "alternar" é perigoso, e um "ligar" não é.

O keepalive não é detalhe#

Sem PINGREQ, o broker fecha a conexão no silêncio — e o sintoma é um painel que para de atualizar de madrugada, quando nada acontece por muito tempo. O cliente daqui tem uma thread própria para isso, e ela nasce junto com a conexão.

Quando o broker recusa#

dataforge
adopt Arcane.IoT as IoT

monitor:
    IoT.mqtt("127.0.0.1", 1, "x", "", "", 60, void, 1)
handle Error as e:
    out e.message
    out e.dica              // docker run -p 1883:1883 eclipse-mosquitto

E quando ele responde mas nega, o código volta traduzido: 5 é "não autorizado" — o mais comum de todos, e o que mais confunde, porque a conexão TCP funcionou.