Skip to content

Repository files navigation

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

  Alternative: Boost.MQTT5. With Boost 1.88 or later, the plugin can be built without Paho. It then supports MQTT 5 only. Paho is used whenever it is installed; to choose explicitly, pass these options to Trunk Recorder's cmake:

Option Default Description
-DMQTT_LIBRARY= auto auto (Paho if installed, otherwise Boost), paho or boost
-DMQTT_BOOST_WEBSOCKET= OFF Boost only: support ws:// and wss:// brokers. Roughly doubles the memory needed to compile the plugin.
  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:

Key Required Default Value Type Description
broker ✓ tcp://localhost:1883 string The 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.
topic ✓ string This is the base MQTT topic. The plugin will create subtopics for the different status messages.
unit_topic string Optional topic to report unit stats over MQTT.
message_topic string Optional topic to report trunking messages over MQTT.
console_logs false true/false Optional setting to report console messages over MQTT.
username string If a username is required for the broker, add it here.
password string If a password is required for the broker, add it here.
client_id tr-status-xxxxxxxx string Override the client_id generated for this connection to the MQTT broker.
mqtt_audio false true/false Optional setting to report audio in base64 and call metadata over MQTT.
mqtt_audio_type wav string Control which audio files to emit. wav, m4a (if compression enabled), both, none (only the .json)
qos 0 int Set the MQTT message QOS level
mqtt_version 3 int MQTT protocol version: 3 (3.1.1) or 5. MQTT 5 requires broker support and logs the broker's reason when it closes the connection.
queue_max_age 60 int Seconds a message may wait in the outbound queue (e.g. while the broker is unreachable) before it is discarded as stale.
audio_max_age 300 int As queue_max_age, for mqtt_audio messages.
queue_max_mb 32 int Memory limit for the outbound queue. When exceeded, the oldest queued messages are discarded. Lower this on memory-constrained systems that send audio.
heartbeat_interval 10 int Seconds between QoS 1 heartbeats used to detect a broker connection that has silently stopped delivering. 0 disables.
heartbeat_timeout 30 int Seconds to wait for the broker to acknowledge a heartbeat before reconnecting. Raise this if mqtt_audio is sent over a slow uplink, where large payloads can delay the acknowledgement. 0 disables.

Trunk-Recorder options:

Key Required Default Value Type Description
instanceId trunk-recorder string Append 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,
        "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.

Topic Sub-Topic Retained Description*
topic rates Control channel decode rates
topic config ✓ Trunk-recorder config information
topic systems ✓ List of configured systems
topic system System configuration/startup
topic calls_active List of active calls, updated every second
topic recorders List of all recorders, updated every 3 seconds
topic recorder Recorder status changes
topic call_start New call
topic call_end Completed call
topic audio Audio and metadata of completed call
topic/trunk_recorder status ✓ Plugin status, sent on startup or when the broker loses connection
topic/trunk_recorder console Trunk-Recorder console log messages
topic/trunk_recorder heartbeat Broker liveness check (QoS 1), every heartbeat_interval seconds
unit_topic/shortname call Channel grants
unit_topic/shortname end Call end unit information**
unit_topic/shortname on Unit registration (radio on)
unit_topic/shortname off Unit de-registration (radio off)
unit_topic/shortname ackresp Unit acknowledge response
unit_topic/shortname join Unit group affiliation
unit_topic/shortname data Unit data grant
unit_topic/shortname ans_req Unit answer request
unit_topic/shortname location Unit location update
unit_topic/shortname call_alert Unit-to-unit page (P25 Call Alert); trunk-recorder after v5.2.1
message_topic/shortname messages Trunking 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

State State Type Description
0 MONITORING Call: Active - No recorder is assigned - See mon_state table
1 RECORDING Call: Active - Recorder is assigned
Recorder: Assigned to call [Recording] - Demodulating transmissions
2 INACTIVE Recorder: Assigned to call [Disconnecting] - Detaching from source and demodulator
3 ACTIVE Recorder: Assigned to call [Tuned] - Not recording yet
4 IDLE Recorder: Assigned to call [Squelched] - Not recording, has not timed out
6 STOPPED Recorder: Not assigned to call - Returning to AVAILABLE state
7 AVAILABLE Recorder: Not assigned to call - Free for use
8 IGNORE Recorder: Assigned to call [Ignoring] - Ending call after unexpected data on the voice channel

mon_state

State State Type Description
0 UNSPECIFIED Default state
1 UNKNOWN_TG Not recording: recordUnknown is false and talkgroup is not found in the talkgroup.csv (*not currently implemented)
2 IGNORED_TG Not recording: Talkgroup has the ignore priority (-1) set in the talkgroup.csv
3 NO_SOURCE Not recording: No source exists for the requested voice frequency
4 NO_RECORDER Not recording: No recorders are available or talkgroup priority is too low
5 ENCRYPTED Not recording: Encryption indicated by trunking messages or mode field (E,DE,TE) in the talkgroup.csv
6 DUPLICATE Not recording: [multiSite] This call is a duplicate of a prior call
7 SUPERSEDED Not 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

About

Trunk Recorder Plugin that sends current status over MQTT

Resources

Stars

7 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages