ha_mqtt.c
Native Home Assistant MQTT publisher for the ESP32 Matter lock — see ha_mqtt.h…
Overview
Native Home Assistant MQTT publisher for the ESP32 Matter lock — see ha_mqtt.h for the wire contract this holds with integration/homeassistant.
depends on ha_mqtt.h
flowchart TD announce --> discovery_access_payload announce --> discovery_distance_payload
API
Cstruct ha_msg
One queued observation: the smallest thing that can carry either topic's payload.
Fstatic bool node_name_ok(const char *node)
True for a node name that is safe both as an MQTT topic level and as a bare JSON string, so the discovery payloads below never need escaping.
cfg_load, ha_mqtt_shell_cmdFstatic esp_err_t cfg_set_str(const char *key, const char *value)
Store one string under key in the ha_mqtt namespace, or erase it when value is NULL. Returns ESP_OK on success.
ha_mqtt_shell_cmdFstatic bool cfg_get_str(nvs_handle_t h, const char *key, char *out, size_t len)
Read one string from the ha_mqtt namespace into out. Returns false when the key is absent or does not fit.
cfg_load, cmd_showFstatic bool cfg_load(void)
Load every configured value into s_cfg. Returns false (naming the first missing item) unless the broker is fully provisioned: host, login, node and pinned CA. Authentication is required rather than optional, matching the agent's refusal to connect anonymously without an explicit opt-in.
ha_mqtt_task · calls cfg_get_str, node_name_okFstatic void build_topics(void)
Build every topic once, from the node name the agent also keys its topics on.
ha_mqtt_taskFstatic int discovery_distance_payload(char *buf, size_t len)
Build a Home Assistant MQTT Discovery payload for the Distance sensor entity in millimeters.
announceFstatic int discovery_access_payload(char *buf, size_t len)
Build a Home Assistant MQTT Discovery payload for the Access event entity with available and granted/denied event types.
announceFstatic void announce(void)
Publish retained discovery and online availability, once per connection. Runs on the publisher task, never in the mqtt event callback, because esp_mqtt_client_publish() sends in the caller's context and would deadlock there.
ha_mqtt_task · calls discovery_access_payload, discovery_distance_payloadFstatic void mqtt_event_handler(void *arg, esp_event_base_t base, int32_t event_id, void *data)
esp-mqtt event callback. Runs on the mqtt task and only flips flags; every publish happens on the publisher task, which reads them.
Fstatic esp_err_t client_start(void)
Bring up the TLS client against the pinned CA. Returns ESP_OK once esp-mqtt owns the connection; it reconnects on its own from then on.
ha_mqtt_taskFstatic void ha_mqtt_task(void *arg)
Publisher task: the only place that touches the broker. Everything upstream of it hands over a queue entry and returns immediately.
announce, build_topics, cfg_load, client_startFstatic void ha_mqtt_enqueue(uint8_t kind, int32_t value)
Hand one observation to the publisher task. Drops rather than blocks: the callers are the Aliro reader task and the NimBLE host task running the credential transaction, where the UWB responder holds a ~1.8 ms slot deadline and a stalled broker must never become walk-up latency. A dropped distance sample is replaced by the next block 192 ms later; a dropped access event is only possible behind eight unsent messages, which already means the broker is gone.
ha_mqtt_publish_access, ha_mqtt_publish_distance_cmFvoid ha_mqtt_publish_distance_cm(int32_t cm)
Queue one conditioned approach distance, in centimetres (the estimate the unlock thresholds act on, not a raw block). Never blocks: a full queue drops the sample. Rate-limited to the agent's own interval before it is queued.
ha_mqtt_enqueueFvoid ha_mqtt_publish_access(bool granted)
Queue one credential-independent access verdict. Never blocks: a full queue drops the event. Matches aliro_reader's access-listener signature, so it can be registered directly.
ha_mqtt_enqueueFvoid ha_mqtt_start_once(void)
Bring the publisher up once the station has an address. Idempotent and cheap: it only spawns the publisher task, which then does the NVS read, the TLS connect and every publish. Safe to call from the Matter event callback. No-op when the broker has not been provisioned.
ha_mqtt_shell_cmdFstatic char *read_console_block(size_t max, bool multiline)
Read from the console without going through linenoise, so a secret typed here never enters the shell's in-RAM history where an up-arrow would recall it. In multiline mode, collect until a line containing only ".". Returns a heap string the caller frees, or NULL on overflow or end of input. Nothing is echoed.
ha_mqtt_shell_cmdFstatic void cmd_show(void)
Print what is provisioned and what the publisher is doing. The password is reported as set or unset and never rendered.
ha_mqtt_shell_cmd · calls cfg_get_strFint ha_mqtt_shell_cmd(int argc, char **argv)
hamqtt console command: provision the broker, show state, start. Registered
from app_shell.cpp alongside the other commands.
cfg_set_str, cmd_show, ha_mqtt_start_once, node_name_ok, read_console_block