# MQTT Bridge Implementation for MeshCore This document describes the MQTT bridge implementation that allows MeshCore repeaters to uplink packet data to multiple MQTT brokers. ## Quick Start Guide ### Essential Commands to Get MQTT Repeater Running **1. Connect to device console via repeater login or serial console (115200 baud)** **2. Configure WiFi Credentials** ```bash set wifi.ssid YourWiFiNetwork set wifi.pwd YourWiFiPassword ``` If you wish to upload to the MeshCore Analyzer, also `set mqtt.iata XXX` to a valid IATA airport code. **3. Reboot to Connect to WiFi** ```bash reboot ``` **4. Toggle bridge.source to rx** ```bash set bridge.source rx ``` **5. Verify Configuration** ```bash get wifi.ssid get bridge.enabled get bridge.source get mqtt.origin get mqtt.iata get mqtt1.preset get mqtt2.preset get mqtt3.preset ``` **6. Restart Bridge (if needed)** ```bash # Option A: Toggle bridge off then on set bridge.enabled off set bridge.enabled on # Option B: Full device reboot reboot ``` **That's it!** The device will now: - Connect to WiFi automatically - Start uplinking mesh packets to configured MQTT brokers - By default, publish to Let's Mesh Analyzer US (slot 1) and EU (slot 2) - Use device name as MQTT origin (set automatically) --- ## Overview The MQTT bridge implementation provides: - Up to 3 concurrent MQTT connection slots with built-in presets - Built-in presets for LetsMesh Analyzer (US/EU) and MeshMapper - Custom broker support with username/password authentication - JWT (Ed25519 device signing) authentication for preset brokers - WSS (WebSocket Secure) and direct MQTT transport - Automatic reconnection with exponential backoff - JSON message formatting for status, packets, and raw data - Packet queuing during connection issues - Automatic migration from old configuration format ## Architecture ### Slot-Based Preset System The MQTT bridge uses a slot-based architecture with up to 3 concurrent connections. Each slot can be configured with a built-in preset or custom broker settings. **Built-in Presets:** | Preset | Server | Auth | Transport | |--------|--------|------|-----------| | `analyzer-us` | mqtt-us-v1.letsmesh.net:443 | JWT (Ed25519) | WSS | | `analyzer-eu` | mqtt-eu-v1.letsmesh.net:443 | JWT (Ed25519) | WSS | | `meshmapper` | mqtt.meshmapper.cc:443 | JWT (Ed25519) | WSS | | `meshrank` | meshrank.net:8883 | None (token in topic) | MQTT over TLS | | `custom` | User-configured | Username/Password | MQTT or WSS | | `none` | (disabled) | — | — | **Default Configuration:** - Slot 1: `analyzer-us` - Slot 2: `analyzer-eu` - Slot 3: `none` **Memory Limits:** - With PSRAM: All 3 slots can be active simultaneously - Without PSRAM: Maximum 2 active slots (each WSS/TLS connection requires ~40KB internal heap) - If more slots are configured than the device supports, excess slots show as `(inactive)` in `get mqtt.status` - Slot configurations are preserved in preferences — moving firmware to a PSRAM device activates all slots ### Files #### Core Implementation - `src/helpers/bridges/MQTTBridge.h` - MQTT bridge class definition - `src/helpers/bridges/MQTTBridge.cpp` - MQTT bridge implementation - `src/helpers/MQTTPresets.h` - Preset definitions, CA certificates, and lookup functions - `src/helpers/MQTTMessageBuilder.h` - JSON message formatting utilities - `src/helpers/MQTTMessageBuilder.cpp` - JSON message formatting implementation - `src/helpers/JWTHelper.h` - JWT token generation for Ed25519-based authentication #### Integration - Updated `examples/simple_repeater/MyMesh.h` - Added MQTT bridge support - Updated `examples/simple_repeater/MyMesh.cpp` - Added MQTT bridge integration and raw radio data capture - Updated `src/helpers/CommonCLI.h` - MQTT slot preferences, WiFi, and timezone fields - Updated `src/helpers/CommonCLI.cpp` - MQTT slot CLI commands, migration logic ## Build Configuration To build the MQTT bridge firmware: ```bash # Heltec V3 pio run -e Heltec_v3_repeater_observer_mqtt # Heltec V4 pio run -e heltec_v4_repeater_observer_mqtt # Station G2 pio run -e Station_G2_repeater_observer_mqtt ``` ### Build Flags - `WITH_MQTT_BRIDGE=1` - Enable MQTT bridge (required) - `MQTT_DEBUG=1` - Enable debug logging (optional) - `MQTT_WIFI_TX_POWER` - WiFi TX power level (default: `WIFI_POWER_11dBm`) - `MQTT_WIFI_POWER_SAVE_DEFAULT` - Default WiFi power save mode (0=min, 1=none, 2=max) ## Default Configuration The MQTT bridge comes with the following defaults: - **Origin**: Device name (set automatically) - **IATA**: (must be configured) - **Status Messages**: Enabled - **Packet Messages**: Enabled - **Raw Messages**: Disabled - **TX Messages**: Disabled (RX only by default) - **Status Interval**: 5 minutes (300000 ms) - **Slot 1**: `analyzer-us` (mqtt-us-v1.letsmesh.net:443) - **Slot 2**: `analyzer-eu` (mqtt-eu-v1.letsmesh.net:443) - **Slot 3**: `none` (disabled) - **WiFi SSID**: "ssid_here" (must be configured) - **WiFi Password**: "password_here" (must be configured) - **WiFi Power Save**: "min" (minimum power saving, balanced performance and power) - **Timezone**: "America/Los_Angeles" (Pacific Time with DST support) - **Timezone Offset**: -8 hours (fallback) ## CLI Commands ### MQTT Slot Commands Each slot (1-3) supports the following commands: #### Get Commands - `get mqtt1.preset` - Get slot 1 preset name - `get mqtt2.preset` - Get slot 2 preset name - `get mqtt3.preset` - Get slot 3 preset name - `get mqttN.server` - Get custom server hostname for slot N - `get mqttN.port` - Get custom server port for slot N - `get mqttN.username` - Get custom username for slot N - `get mqttN.password` - Get custom password for slot N - `get mqttN.token` - Get per-slot token (e.g., MeshRank account token) - `get mqttN.topic` - Get custom topic template for slot N #### Set Commands - `set mqtt1.preset analyzer-us` - Set slot 1 to LetsMesh Analyzer US - `set mqtt1.preset analyzer-eu` - Set slot 1 to LetsMesh Analyzer EU - `set mqtt1.preset meshmapper` - Set slot 1 to MeshMapper - `set mqtt1.preset meshrank` - Set slot 1 to MeshRank (requires token) - `set mqtt1.preset custom` - Set slot 1 to custom broker (configure server/port/username/password) - `set mqtt1.preset none` - Disable slot 1 - `set mqttN.server ` - Set custom server hostname for slot N - `set mqttN.port ` - Set custom server port for slot N (1-65535) - `set mqttN.username ` - Set custom username for slot N - `set mqttN.password ` - Set custom password for slot N - `set mqttN.token ` - Set per-slot token (required for MeshRank preset) - `set mqttN.topic