IoT Networking — MQTT

On top of WiFi & HTTP, the Zephyr HAL adds MQTT for publish/subscribe messaging. Mqtt is a thin class: construction carries the broker URI and client id, and the client completes its session in a background poll thread that also owns keepalives and message acks — so messages keep arriving while your main code does other work.


Basic usage

import { Mqtt } from '@typecad/hal';
import { UART0 } from '@typecad/board';

const mqtt = new Mqtt('mqtt://broker.local:1883', { clientId: 'esp32-client' });

mqtt.onMessage((topic, payload) => {
  UART0.writeLine(topic + ': ' + payload);   // fires for every subscribed publish
});

mqtt.connect();                 // open the session
mqtt.subscribe('sensors/temperature');
mqtt.subscribe('cmd/#');        // wildcard: all sub-topics under cmd/

// later, publish a reading
mqtt.publish('sensors/temperature', '23.4');

Waiting for the session

connect() returns void — the session finishes (CONNACK) on the background thread. Poll linked(), and on a flaky link retry in a loop until it flips:

for (let i = 0; i < 10; i++) {
  mqtt.connect();
  for (let j = 0; j < 8; j++) {
    if (mqtt.linked()) { break; }
    Time.sleep(250);
  }
  if (mqtt.linked()) { break; }
}

Publish, check, disconnect

if (mqtt.linked()) {
  mqtt.publish('status', 'online');
}
mqtt.disconnect();   // disconnect and free the client

Things worth knowing:

  • URIs: mqtt://host:port (plain TCP, default port 1883) and mqtts://host:port (TLS, default 8883). Hostnames resolve through Zephyr’s DNS resolver; numeric IPs work directly.
  • QoS: subscriptions and publishes ride QoS 1 (at-least-once). Incoming QoS-1 messages are acked by the client itself, so the broker does not resend.
  • Payloads: topic and payload arrive as C strings valid until the next message — copy what you need inside the handler.
  • mqtts:// is encrypted but the broker’s identity is not verified (there is no CA-pinning fact on this class yet — the analogue of Request’s caCert). Treat it as encrypted-but-unverified until that lands.
  • Mqtt needs a networked target: using it on a board with no WiFi radio (the nRF52840-based XIAO, for example) is a build error naming an ESP32 target.

mDNS and OTA are not available on Zephyr. For those, use the Zephyr APIs directly via rawCpp().


API Reference

MethodDescription
new Mqtt(uri, { clientId })Construct with the broker URI (mqtt:// or mqtts://) and client id.
connect()Open the session — returns void; poll linked() for CONNACK.
onMessage(handler)Set a (topic, payload) => void callback for received publishes.
subscribe(topic)Subscribe to a topic filter (supports # / + wildcards).
publish(topic, data)Publish a message (QoS 1).
linked()true while the broker session is up.
close()Disconnect and free the client.