Trunk Recorder MQTT Plugin

December 31, 2025 · View on GitHub

Discord   

Trunk Recorder MQTT Plugin

This is a plugin for Trunk Recorder that publish the current status over MQTT. External programs can use the MQTT messages to collect and display information on monitored systems.

Requires trunk-recorder 5.0 or later, and Paho MQTT libraries

Install

  1. Clone Trunk Recorder source following these instructions.

  2. Install the Paho MQTT C & C++ Libraries.

  If your package manager provides recent Paho MQTT libraries, e.g:

sudo apt install libpaho-mqtt-dev libpaho-mqttpp-dev

  If not, you may build and install these libraries from source:

  - Install Paho MQTT C

git clone https://github.com/eclipse/paho.mqtt.c.git
cd paho.mqtt.c

cmake -Bbuild -H. -DPAHO_ENABLE_TESTING=OFF -DPAHO_BUILD_STATIC=ON  -DPAHO_WITH_SSL=ON -DPAHO_HIGH_PERFORMANCE=ON
sudo cmake --build build/ --target install
sudo ldconfig

  - Install Paho MQTT C++

git clone https://github.com/eclipse/paho.mqtt.cpp
cd paho.mqtt.cpp

cmake -Bbuild -H. -DPAHO_BUILD_STATIC=ON
sudo cmake --build build/ --target install
sudo ldconfig
  1. Build and install the plugin:

  This pluigin source should be cloned into the /user_plugins directory of the Trunk Recorder 5.0+ source tree. It will be built and installed along with Trunk Recorder.

cd [your trunk-recorder github source directory]
cd user_plugins
git clone https://github.com/TrunkRecorder/tr-plugin-mqtt
cd [your trunk-recorder build directory]
sudo make install

NOTE: Plugins will be automatically built and installed with Trunk Recorder. To update either Trunk Recorder or a plugin, simply cd into the appropriate git directory and git pull. Refer to the above instructions to make install any updates.

Configure

Plugin options:

KeyRequiredDefault ValueTypeDescription
brokertcp://localhost:1883stringThe URL for the MQTT Message Broker. It should include the protocol used: tcp, ssl, ws, wss and the port, which is generally 1883 for tcp, 8883 for ssl, and 443 for ws.
topicstringThis is the base MQTT topic. The plugin will create subtopics for the different status messages.
unit_topicstringOptional topic to report unit stats over MQTT.
message_topicstringOptional topic to report trunking messages over MQTT.
console_logsfalsetrue/falseOptional setting to report console messages over MQTT.
usernamestringIf a username is required for the broker, add it here.
passwordstringIf a password is required for the broker, add it here.
client_idtr-status-xxxxxxxxstringOverride the client_id generated for this connection to the MQTT broker.
mqtt_audiofalsetrue/falseOptional setting to report audio in base64 and call metadata over MQTT.
mqtt_audio_typewavstringControl which audio files to emit. wav, m4a (if compression enabled), both, none (only the .json)
qos0intSet the MQTT message QOS level

Trunk-Recorder options:

KeyRequiredDefault ValueTypeDescription
instanceIdtrunk-recorderstringAppend an instance_id key to identify the trunk-recorder instance sending MQTT messages.

Plugin Usage:

See the included config.json for an example how to load this plugin.

    "plugins": [
    {
        "name": "MQTT Status",
        "library": "libmqtt_status_plugin.so",
        "broker": "tcp://io.adafruit.com:1883",
        "topic": "robotastic/feeds",
        "unit_topic": "robotastic/units",
        "username": "robotastic",
        "password": "",
        "console_logs": true,
        "mqtt_audio": false,
        "mqtt_qos": 0,
    }]

If the plugin cannot be found, or it is being run from a different location, it may be necessary to supply the full path:

        "library": "/usr/local/lib/trunk-recorder/libmqtt_status_plugin.so",

MQTT Messages

The plugin will provide the following messages to the MQTT broker depending on configured topics.

TopicSub-TopicRetainedDescription*
topicratesControl channel decode rates
topicconfigTrunk-recorder config information
topicsystemsList of configured systems
topicsystemSystem configuration/startup
topiccalls_activeList of active calls, updated every second
topicrecordersList of all recorders, updated every 3 seconds
topicrecorderRecorder status changes
topiccall_startNew call
topiccall_endCompleted call
topicaudioAudio and metadata of completed call
topic/trunk_recorderstatusPlugin status, sent on startup or when the broker loses connection
topic/trunk_recorderconsoleTrunk-Recorder console log messages
unit_topic/shortnamecallChannel grants
unit_topic/shortnameendCall end unit information**
unit_topic/shortnameonUnit registration (radio on)
unit_topic/shortnameoffUnit de-registration (radio off)
unit_topic/shortnameackrespUnit acknowledge response
unit_topic/shortnamejoinUnit group affiliation
unit_topic/shortnamedataUnit data grant
unit_topic/shortnameans_reqUnit answer request
unit_topic/shortnamelocationUnit location update
message_topic/shortnamemessagesTrunking messages

* Some messages have been changed for consistency. Please see links for examples and notes.
** end is not a trunking message, but sent after trunk-recorder ends the call. This can be used to track conventional non-trunked calls.

Trunk Recorder States

Trunk Recorder uses state definitions to manage call flows, recorder assignment, and demodulator operation. The MQTT plugin will include this information when possible. Below is a summary of these states, but not all may appear in MQTT messages.

call_state / rec_state

StateState TypeDescription
0MONITORINGCall: Active - No recorder is assigned - See mon_state table
1RECORDINGCall: Active - Recorder is assigned
Recorder: Assigned to call [Recording] - Demodulating transmissions
2INACTIVERecorder: Assigned to call [Disconnecting] - Detaching from source and demodulator
3ACTIVERecorder: Assigned to call [Tuned] - Not recording yet
4IDLERecorder: Assigned to call [Squelched] - Not recording, has not timed out
6STOPPEDRecorder: Not assigned to call - Returning to AVAILABLE state
7AVAILABLERecorder: Not assigned to call - Free for use
8IGNORERecorder: Assigned to call [Ignoring] - Ending call after unexpected data on the voice channel

mon_state

StateState TypeDescription
0UNSPECIFIEDDefault state
1UNKNOWN_TGNot recording: recordUnknown is false and talkgroup is not found in the talkgroup.csv (*not currently implemented)
2IGNORED_TGNot recording: Talkgroup has the ignore priority (-1) set in the talkgroup.csv
3NO_SOURCENot recording: No source exists for the requested voice frequency
4NO_RECORDERNot recording: No recorders are available or talkgroup priority is too low
5ENCRYPTEDNot recording: Encryption indicated by trunking messages or mode field (E,DE,TE) in the talkgroup.csv
6DUPLICATENot recording: [multiSite] This call is a duplicate of a prior call
7SUPERSEDEDNot recording: [multiSite] This call is a duplicate of a subsequent call with a site precedence indicated in the talkgroup.csv

MQTT Brokers

Mosquitto MQTT Broker

The Mosquitto MQTT is an easy way to have a local MQTT broker. It can be installed from a lot of package managers.

This broker does not impose a limit on the length of MQTT messages, and will handle packets up to 256 MB in size by default.

Starting it on a Mac:

/opt/homebrew/sbin/mosquitto -c /opt/homebrew/etc/mosquitto/mosquitto.conf

NanoMQ

The NanoMQ broker is a lightweight alternative, but additional configuration may be required for Trunk Recorder systems with a large number of recorders or heavy call volume.

This broker does impose a limit on the length of MQTT messages, and the max_packet_size default of 10 KB may generate MQTT error [-3]: Disconnected errors with this plugin.

# #============================================================
# # NanoMQ Broker
# #============================================================

mqtt {
    property_size = 32
    max_packet_size = 10KB
    max_mqueue_len = 2048
    retry_interval = 10s
    keepalive_multiplier = 1.25
...

Editing /etc/nanomq.conf and increasing the packet size to 100 KB or more should be sufficient for MQTT messages generated by this plugin. If mqtt_audio is enabled packet size will need to be raised significantly.

Docker

A prebuilt docker image containing Trunk Recorder and this MQTT plugin is also available via a community respository.

thegreatcodeholio/trunk-recorder-mqtt:latest