Files
arduino-home-assistant/docs/mqtt-usage.md
T

5.3 KiB
Raw Blame History

MQTT usage

Callbacks and tuning

HAMqtt supports optional callbacks and PubSubClient tuning:

void onMessage(const char* topic, const uint8_t* payload, uint16_t length) { /* ... */ }
void onConnected() { /* ... */ }
void onDisconnected() { /* ... */ }
void onStateChanged(HAMqtt::ConnectionState state) { /* ... */ }

void setup() {
    mqtt.onMessage(onMessage);
    mqtt.onConnected(onConnected);
    mqtt.onDisconnected(onDisconnected);
    mqtt.onStateChanged(onStateChanged);
    mqtt.setBufferSize(512);   // default 256
    mqtt.setKeepAlive(60);     // seconds, default 15
    mqtt.begin("192.168.1.50", "user", "pass");
}

Custom subscriptions

Subscribe after each successful connection (for example in onConnected), because subscriptions are tied to the MQTT session:

void onConnected() {
    mqtt.subscribe("my/custom/topic");
}

Handle payloads in onMessage.

Publishing arbitrary payloads

mqtt.publish("customTopic", "payload", false);  // not retained
mqtt.publish("customTopic", "payload", true);     // retained

Availability

Shared availability (recommended): one availability topic for the whole device — works well with Last Will (LWT):

device.enableSharedAvailability();
device.setPayloadAvailable("up");
device.setPayloadNotAvailable("down");
device.enableLastWill();   // broker publishes offline when TCP drops
// device.setAvailability(false);  // optional: start as offline

Per-entity availability: call someEntity.setAvailability(true/false) on each type. Does not use LWT the same way as shared mode; see examples under examples/availability/.

Custom per-entity payloads are supported:

sensor.setPayloadAvailable("ready");
sensor.setPayloadNotAvailable("lost");

For multi-topic availability discovery, add full MQTT topics and a mode:

sensor.setAvailabilityMode("all");
sensor.addAvailabilityEntry("bridge/status");
sensor.addAvailabilityEntry("sensor/status", "{{ value_json.state }}");

Discovery helpers by entity

Common entity discovery metadata is available on most entity classes:

entity.setEnabledByDefault(false);
entity.setEntityPicture("https://example.com/entity.png");
entity.setQos(1);
entity.setEncoding("utf-8");
entity.setEntityCategory("diagnostic");

Read-only sensor presentation/template helpers:

sensor.setSuggestedDisplayPrecision(2);
sensor.setValueTemplate("{{ value_json.temperature }}");
sensor.setJsonAttributesTemplate("{{ value_json.attrs | tojson }}");
sensor.setLastResetValueTemplate("{{ value_json.last_reset }}");
sensor.setDeviceClass("enum");
sensor.setOptions("idle;charging;discharging;fault");

Writable entity template/payload helpers:

mySwitch.setPayloadOn("ENABLE");
mySwitch.setPayloadOff("DISABLE");
mySwitch.setStateOn("running");
mySwitch.setStateOff("stopped");
mySwitch.setValueTemplate("{{ value_json.state }}");
mySwitch.setCommandTemplate("{{ value_json.command }}");

myNumber.setPayloadReset("RESET");
myNumber.setCommandTemplate("{{ value | float | round(1) }}");

mySelect.setCommandTemplate("{{ value_json.choice }}");
myText.setCommandTemplate("{{ value_json.text }}");
myButton.setPayloadPress("PRESS");

Compiler macros

Defined in ArduinoHADefines.h or via build flags.

  • ARDUINOHA_DISABLE_STDFUNCTION — disables the default capturing-lambda and std::bind overloads on entity command APIs. Use it on targets without a complete std::function implementation or where code size/RAM matters (constrained AVR builds are the usual case). ESP8266/ESP32 support the overloads. HAMqtt lifecycle callbacks remain ordinary function pointers.
  • ARDUINOHA_DEBUG — enables ArduinoHA logging by default and sets the initial maximum verbosity to Debug. Without this flag, structured logs are compiled in but remain disabled until you call arduinoHASetLogEnabled(true).

Structured logging is available through:

arduinoHASetLogEnabled(true);
arduinoHASetLogLevel(ArduinoHALogLevel::Trace);

class MyLogSink : public ArduinoHALogSink {
public:
    void log(const ArduinoHALogMessage& msg) override {
        Serial.print("[");
        Serial.print(arduinoHALogLevelTag(msg.level));
        Serial.print("][aha.");
        Serial.print(msg.subsystem);
        Serial.print("] ");
        Serial.println(msg.text);
    }
};

arduinoHALog(...) and arduinoHALogf(...) support subsystem-tagged messages such as mqtt, discovery, availability, serializer, entity, and device. Install a sink when you want those messages to join your application’s normal serial or structured log stream.

Applications that use Wi-Fi can register arduinoHASetNetworkStatusFn with a callback returning WiFi.status(). Publish failure diagnostics can then include the current Wi-Fi status without coupling ArduinoHA to a particular network library.

Exclude unused device types (saves flash from vtables), e.g.:

EX_ARDUINOHA_BINARY_SENSOR, EX_ARDUINOHA_BUTTON, EX_ARDUINOHA_CAMERA, EX_ARDUINOHA_COVER, EX_ARDUINOHA_DEVICE_TRACKER, EX_ARDUINOHA_DEVICE_TRIGGER, EX_ARDUINOHA_FAN, EX_ARDUINOHA_HVAC, EX_ARDUINOHA_LIGHT, EX_ARDUINOHA_LOCK, EX_ARDUINOHA_NUMBER, EX_ARDUINOHA_SCENE, EX_ARDUINOHA_SELECT, EX_ARDUINOHA_SENSOR, EX_ARDUINOHA_SWITCH, EX_ARDUINOHA_TAG_SCANNER