Integração MQTT
O MQTT liga o HyperVisu ao mundo publish/subscribe: Zigbee2MQTT, Tasmota, Shelly (modo MQTT), ESPHome, gateways de energia e qualquer firmware personalizado que comunique com um broker MQTT. O HyperVisu é um cliente MQTT — subscreve os tópicos nos quais os dispositivos publicam o seu estado e publica comandos nos tópicos que os dispositivos escutam. Não há polling: um dispositivo que altere o seu estado publica, e o widget atualiza imediatamente.
Um broker fica no meio. Pode ser um que já execute (Mosquitto, EMQX, o fornecido com uma instalação Zigbee2MQTT, …) ou o broker integrado no HyperVisu, que o servidor pode executar autonomamente para que os dispositivos se liguem diretamente a ele (ver "The Built-in MQTT Broker"). Tudo o que consta neste artigo aplica-se a ambos os casos — o broker integrado é um broker comum, acedido através de uma ligação normal.
O que necessita: o endereço e a porta do broker, as suas credenciais se forem exigidas, e os tópicos do dispositivo juntamente com o formato do payload — obtidos a partir da documentação do dispositivo ou lidos diretamente do broker através do navegador de tópicos (abaixo).
Ligações. Ative primeiro o MQTT Protocol na página Services (ver "Services & Protocols"); está desativado num servidor novo. O MQTT suporta múltiplas ligações: uma ligação por broker (ver "Connections"). Em Add connection, selecione o cartão MQTT: o diálogo solicita um Instance Name, o Broker address, a Port, o Client ID e as credenciais, disponibilizando um botão Test. O CA certificate e as Broker options (Keepalive, Default QoS, Availability topic, Clean session) não estão presentes no diálogo: configure-os na ligação guardada, que abre no respetivo editor assim que clicar em Create connection. O editor de ligação inclui:
| Campo | Descrição |
|---|---|
| Broker address | Host, ou um URL completo: mqtt://, mqtts://, ws://, wss:// (um host simples assume mqtt://). Qualquer caminho no endereço é mantido, por exemplo ws://192.168.1.30/mqtt. |
| Port | A porta de escuta — normalmente 1883 para MQTT simples e 8883 para MQTT sobre TLS. Introduza-a sempre: no diálogo Add connection, uma porta vazia é guardada como 1883 independentemente do esquema, e o campo Port sobrepõe-se a qualquer porta especificada no endereço. |
| Username / Password | Deixe em branco para um broker anónimo. |
| Client ID | Deixe em branco para gerar um a partir do endereço MAC do servidor. |
| Accept self-signed certificates | Apresentado apenas para mqtts:// / wss://. Desativado por defeito: o certificado do broker deve ser assinado por uma autoridade fidedigna. Quando ativado, o certificado não é de todo verificado. |
| CA certificate | Apresentado apenas para TLS: o certificado PEM da autoridade que assinou o broker, caso não seja pública. |
| Keepalive | Período durante o qual uma ligação silenciosa pode permanecer aberta antes de um ping (por defeito 60 s). |
| Default QoS | 0 · at most once, 1 · at least once ou 2 · exactly once — utilizado por todos os objetos que não definam o seu próprio valor. |
| Availability topic / Announce HyperVisu availability | Onde o HyperVisu publica online / offline para si próprio (por defeito hypervisu/status, com flag retained). O broker publica offline em seu nome caso a ligação caia. |
| Clean session | Ativado (por defeito): o broker elimina as subscrições quando a ligação cai e o HyperVisu subscreve novamente ao restabelecer a ligação. Desative apenas para um broker que deva colocar mensagens em fila enquanto o HyperVisu estiver desligado. |
O botão Test numa ligação MQTT executa um teste real: o servidor liga-se ao broker e aguarda pela sua confirmação (dentro de 10 s). Um resultado positivo indica Connection succeeded. No diálogo Add connection, o Test valida os valores introduzidos antes de criar a ligação. Numa ligação guardada, o Test verifica a ligação guardada e não os campos que ainda não gravou: clique primeiro em Save connection e depois em Test. Um teste bem-sucedido prova que o endereço, a porta, as credenciais e as definições TLS são aceites pelo broker; não prova que qualquer tópico contenha dados.
O estado da ligação indica Connected enquanto a comunicação com o broker estiver ativa. Se o broker ficar indisponível, são efetuadas tentativas de reconexão a cada poucos segundos, sem limite — nunca exige o reinício do servidor.
📘 Nota: Depois de criar ou guardar uma ligação, surge Apply changes na barra lateral com um contador. A ligação já funciona sem isso; a aplicação recarrega a configuração do servidor e limpa o contador.

Associação de um objeto (ver "Binding MQTT" abaixo). Por cada objeto introduz-se um Topic; a administração armazena-o como <connection>:<topic>, permitindo que dois brokers utilizem o mesmo nome de tópico. A direção do objeto determina o comportamento:
| Direção | Comportamento |
|---|---|
| In | Subscreve o tópico (tópico de estado). São permitidos wildcards: + para um nível, # para os restantes. |
| Out | Publica no tópico (tópico de comando). Tem de ser um tópico concreto — sem wildcards. |
| In/Out | Subscreve e publica no mesmo tópico. Apenas correto para dispositivos que mantêm estado retido num único tópico; prefira dois objetos (um In, um Out). |
O codec de payload — a forma como o payload é convertido num valor e vice-versa — corresponde à string de tipo de dados do objeto, gerada pelo editor a partir destes campos:
| Campo | Armazenado como | Significado |
|---|---|---|
| Payload format | — / PATH= | Raw value: a totalidade do payload é o valor. JSON: o valor é lido no JSON path (state, sensor.temperature, values[0]). |
| ON token / OFF token | ON= / OFF= | Para objetos booleanos: o que o dispositivo escreve e espera para verdadeiro/falso (ex. ON / OFF). Sem tokens, true/false, 1/0, on/off são interpretados na receção e é publicado true/false. |
| Scale / Offset | SCALE= / OFFSET= | Leitura: valor = raw × escala + offset; a publicação utiliza a fórmula inversa, raw = (valor − offset) ÷ escala. Um objeto de comando e o seu respetivo objeto de feedback utilizam, portanto, a mesma escala. |
| Payload template | PUB= | Modelo de publicação opcional; {{value}} é substituído pelo valor, ex. {"state":"{{value}}"}. Deixe em branco para publicar apenas o valor simples. |
| QoS | QOS= | Broker default, 0, 1 ou 2 para este comando. |
| Retain published messages | RETAIN=1 | Desativado por defeito. |
| Minimum interval (ms) | THROTTLE= | Sensores com transmissões muito frequentes são limitados a esta taxa (por defeito 100 ms); o último valor é sempre entregue. O valor 0 desativa o limite. |
A string assume o formato TYPE:param:param… — por exemplo BOOL:PATH=state:ON=ON:OFF=OFF ou FLOAT:SCALE=0.3937:PUB={"brightness":{{value}}}. Uma string vazia significa "utilizar o payload raw como tipo do objeto". O editor de objetos não possui um campo de tipo de dados: o tipo é o apresentado no campo em que clica no navegador de tópicos (abaixo), e o clique ajusta o tipo do objeto em conformidade. Objetos de cor (RGB) aceitam {"r","g","b"}, {"red","green","blue"}, [r,g,b], #RRGGBB e 255,128,0 na receção, e publicam {"r":…,"g":…,"b":…} exceto se um template especificar outro formato.
⚠️ Aviso: Um comando com flag de retenção (retain) é reexecutado sempre que o dispositivo se volta a ligar ao broker. Retenha estados, não comandos — o editor emite um aviso quando ativa a retenção num objeto de saída (Out).
Navegador de tópicos. O MQTT é o único protocolo cujos endereços podem ser lidos diretamente da rede. No editor de objetos, em MQTT topic configuration, clique em Scan broker: o servidor escuta todo o broker durante quatro segundos e indica quantos tópicos foram recebidos (os tópicos com retenção chegam de imediato, pelo que uma pesquisa curta apresenta a maioria dos dados relevantes; para um dispositivo sem retenção, force uma nova leitura e repita a pesquisa). A lista está limitada a 500 tópicos. O editor de objetos não permite pesquisar apenas uma parte do broker: abra Topic e escreva em Search topics… para filtrar os tópicos detetados, ou introduza o tópico completo manualmente. Cada linha apresenta o tópico e o seu último payload, com o indicador retained. Selecione um tópico e:
- num payload JSON, todos os campos são listados em Pick the value this object should follow — um único clique define o caminho JSON, o tipo de objeto e, para booleanos, os tokens ON/OFF na sintaxe exata do dispositivo;
- num payload simples, Use the raw payload as
preenche o tipo correspondente.
Escolha o tópico antes de clicar num campo: selecionar outro tópico reinicializa o formato do payload, o caminho JSON e os tokens. O clique não preenche os campos Scale e Offset.
Pode introduzir manualmente um tópico não detetado na pesquisa — um tópico de comando pode nunca ter sido publicado e um objeto de entrada pode requerer um wildcard. Escreva-o em Topic e clique em Use "…" na lista.

Comportamentos relevantes
- Estado imediato após reinício. As mensagens retidas são reenviadas pelo broker a cada ligação/reconexão, permitindo que os widgets apresentem valores sem aguardar pela próxima publicação do dispositivo.
- Sem feedback fictício. Um comando só é confirmado quando o dispositivo publica o seu tópico de estado (ou quando o broker o reenvia) — exatamente como os objetos de estado KNX. Se o dispositivo estiver offline, o widget não simula a alteração.
- Comandos durante uma falha. Os comandos com QoS 1 ou 2 são colocados em fila enquanto o broker estiver inacessível e entregues após a reconexão; os comandos com QoS 0 enviados a um broker inacessível falham e são registados em log.
- Proteção. Payloads superiores a 64 KB são descartados com um aviso; é aberta apenas uma subscrição por filtro de tópico distinto, independentemente de quantos objetos o partilham.
Exemplo prático — uma lâmpada regulável Zigbee2MQTT
O Zigbee2MQTT publica o estado da lâmpada em formato JSON no tópico zigbee2mqtt/lamp ({"state":"ON","brightness":178}) e aceita comandos em zigbee2mqtt/lamp/set. O valor de luminosidade varia entre 0 e 254.
- Crie uma ligação MQTT para o broker (ver "Connections"): endereço do broker
192.168.1.10, porta1883, e as credenciais do broker Zigbee2MQTT, se existirem. Clique em Test — deve indicar sucesso. - Em Devices, adicione um widget Dimmer com o nome "Candeeiro escritório". Em Protocol, selecione a ligação do broker através do nome atribuído. O dispositivo surge com quatro objetos: Switch ON/OFF, Switch Feedback, Dimming setpoint e Dimming feedback.
- Em Switch ON/OFF (o comando on/off): introduza
zigbee2mqtt/lamp/setem Topic e clique em Use "…" na lista. Defina ON token comoON, OFF token comoOFFe Payload template como{"state":"{{value}}"}. Digite os tokens: os termos cinzentosONeOFFsão apenas indicativos; sem tokens, o interruptor publicatrueoufalse. - Em Switch Feedback (o estado on/off): clique em Scan broker, selecione
zigbee2mqtt/lampe clique no campostate— o editor configura o caminho JSONstatee os tokensON/OFF. - Em Dimming setpoint (o comando de regulação): tópico
zigbee2mqtt/lamp/set, Payload template{"brightness":{{value}}}, Scale0.3937, Offset0. - Em Dimming feedback (o estado de regulação): tópico
zigbee2mqtt/lamp, clique no campobrightnesse defina a mesma Scale0.3937. Este valor corresponde a cerca de100/254: os valores de entrada são multiplicados por ele (0–254 em Zigbee passa a 0–100%), e os valores de saída são divididos por ele (0–100% passa a 0–254). - Clique em Save object em cada objeto, clique depois em Apply changes na barra lateral e confirme.
- Ajuste a luminosidade para
50 %na aplicação. A lâmpada recebe aproximadamente127e o feedback reporta cerca de50 %. O cursor confirma a posição através do tópico de estado; ajustar a lâmpada pelo comando físico atualiza igualmente a aplicação.
📘 Nota: O valor enviado não é arredondado:
50 %é publicado como127.000254. O editor de objetos não tem campo de tipo de dados, pelo que não é possível forçar o envio de um número inteiro num objeto de comando. Confirme se a lâmpada aceita valores de regulação decimais.
Associação MQTT
Os objetos MQTT são configurados no diálogo de definições do objeto (abra o objeto com Edit, ver "Object Settings, Logging & Notifications"). A secção específica do protocolo está dividida em três cartões:
MQTT topic configuration
| Campo | Descrição |
|---|---|
| Topic | O tópico que este objeto subscreve (In: tópico de estado — wildcards + e # permitidos) ou publica (Out: tópico de comando — sem wildcards). Selecione-o na lista após executar Scan broker, ou introduza-o manualmente. O endereço armazenado é <connection>:<topic>. |
| Scan broker | Escuta o broker durante alguns segundos e lista os tópicos detetados, cada um com o seu Last payload e o badge retained. Com um tópico selecionado, um payload JSON apresenta os seus campos em Pick the value this object should follow — um clique preenche o caminho JSON, o tipo de dados e os tokens ON/OFF; um payload simples apresenta Use the raw payload as |
| Payload format | Raw value (a totalidade do payload é o valor) ou JSON com um JSON path (state, sensor.temperature, values[0]). |
| ON token / OFF token | Objetos booleanos: o que o dispositivo escreve e espera para verdadeiro/falso (ex. ON / OFF). |
Publicação (objetos de saída - Out)
| Campo | Descrição |
|---|---|
| Payload template | Opcional. {{value}} é substituído pelo valor; deixe em branco para publicar apenas o valor simples. |
| QoS | Broker default, 0, 1 ou 2 — a garantia de entrega para este comando. |
| Retain published messages | Desativado por defeito. Um comando com retenção é reexecutado sempre que o dispositivo se liga novamente — retenha estados, não comandos. |
Subscrição (objetos de entrada - In)
| Campo | Descrição |
|---|---|
| Minimum interval (ms) | Sensores de transmissão rápida são limitados a esta taxa (por defeito 100 ms); o último valor é sempre entregue. O valor 0 desativa o filtro. |
| Scale / Offset | Objetos numéricos: valor = raw × escala + offset na receção, a fórmula inversa na publicação. |
Os campos são armazenados na string de tipo de dados do objeto (ex. BOOL:PATH=state:ON=ON:OFF=OFF) — a sintaxe, o navegador de tópicos e o exemplo prático constam no capítulo MQTT acima.
