ESP32 MQTT library

by OXRS Core Team



This library wraps up all MQTT related functions in an easy-to-use API, ensuring OXRS compatible events and config/command handlers. It includes the following;

  • MQTT broker connection and re-connection attempts
  • Callbacks for connect/disconnect events
  • Callbacks for JSON messages received on the config/command topics
  • Simple API for publishing JSON-based status and telemetry data

By using this library you can be sure your firmware will adhere to the OXRS standards and be compatible with other parts of the OXRS eco-system.

How does it work?

This library is a wrapper around the Arduino PubSubClientopen in new window library by Nick O'Leary. It forms the cornerstone of OXRS compatibility since MQTT is the protocol used for configuration, commands and status/telemetry reporting.

The library will automatically publish and subscribe to various topics, depending on how you use it;

stat/<clientid>/lwtPublishes {"online":true|false} to this topic when connected/disconnected from the MQTT broker
stat/<clientid>Publishes JSON status messages to this topic via publishStatus()
tele/<clientid>Publishes JSON telemetry messages to this topic via publishTelemetry()
stat/<clientid>/adoptPublishes JSON adoption messages to this topic via publishAdopt()
stat/<clientid>/logLog messages can be published to this topic (get topic via getLogTopic())
conf/<clientid>Subscribes to this topic for JSON config messages and passes them on to your onConfig callback
cmnd/<clientid>Subscribes to this topic for JSON command messages and passes them on to your onCommand callback


These topics will be different if you set a topic prefix or suffix. E.g. a topic prefix of home and suffix of oxrs would result in a LWT topic of home/stat/<clientid>/oxrs/lwt



The library needs to be initialised with an instance of PubSubClient, which can be created for either WiFi or Ethernet connections. You also need to register a callback on your PubSubClient for incoming MQTT messages, and pass these events down to the MQTT library;

// MQTT client
PubSubClient _mqttClient(_client);
OXRS_MQTT _mqtt(_mqttClient);

void _mqttCallback(char * topic, byte * payload, int length) 
  // Pass down to our MQTT handler and check it was processed ok
  int state = _mqtt.receive(topic, payload, length);
  switch (state)
      Serial.println(F("Empty MQTT payload received"));
      Serial.println(F("Failed to deserialise MQTT JSON payload"));
      Serial.println(F("No MQTT config handler"));
      Serial.println(F("No MQTT command handler"));

The library will return a status code from .receive() indicating if it was able to successfully process the message. See OXRS_MQTT.hopen in new window for the full list of return codes.

Client ID

A unique client id for the MQTT connection must be specified. Typically we use the last 6 bytes of the device MAC address, but you can use anything you like. The client id must be unique since if another device attempts to connect with the same client id, the broker will boot any existing connections with the same id. See hereopen in new window for more details.

Broker Details

You need to tell the library where and how to connect to your MQTT broker of choice;

Broker ConfigDescription
setBrokerMQTT broker IP address or hostname, and port (typically 1883)
setAuthOptional, the username and password to authenticate with your MQTT broker
setTopicPrefixOptional, a topic prefix applied to all subscriptions and publishes
setTopicSuffixOptional, a topic suffix applied to all subscriptions and publishes

Only setBroker() is mandatory, the rest are optional.


Next add your callbacks for the various events supported by the library and register them with the MQTT library;

Callback RegisterDescription
onConnectedSuccessfully connected to the configured MQTT broker
onDisconnectedConnection to the configured MQTT broker has dropped
onConfigJSON configuration payload received on the conf/<clientid> topic
onCommandJSON command payload received on the cmnd/<clientid> topic

These are all optional, for example the State Monitor firmware has no need for the onCommand callback.

Program Loop

Finally your firmware needs to call the MQTT library .loop() method as often as possible, e.g. typically inside your main program loop() method. This allows the library to check for incoming MQTT messages, process outgoing messages, and do any other internal housekeeping.


The library makes it very easy to publish JSON data by providing a set of simple APIs;

Publish APITopicRetainedDescription
publishStatusstat/<clientid>falsePublish a JSON status message, e.g. when a button event is detected
publishTelemetrytele/<clientid>falsePublish a JSON telemetry message, e.g. when publishing regular sensor data
publishAdoptstat/<clientid>/adopttruePublish a JSON adoption message, typically firmware and network details plus JSON config/command schemas

The adoption message is optional but is used by downstream systems in the OXRS eco-system to identify the device and provide a means for building self-describing configuration and control systems/UIs.


Typically you publish your adoption message in the onConnected callback so anything listening is alerted to your presence as soon as you come online


Download the latest version of the library on Githubopen in new window.

A good place to look for an example of how to use this MQTT library is in the Rack32 library found hereopen in new window.

Supported Hardware

This library is compatible with any Arduino-based hardware, including ESP32, ESP8266 and AVR microprocessors.


When running on AVR MCUs the max MQTT message size is reduced to only 256 bytes, due to memory constraints on these devices. However for ESP32 and ESP8266 devices the max MQTT message size is 16384 bytes.



Found hereopen in new window.