{"id":30872953,"url":"https://github.com/trunkrecorder/tr-plugin-mqtt","last_synced_at":"2025-09-07T22:47:23.023Z","repository":{"id":66958081,"uuid":"497945099","full_name":"TrunkRecorder/tr-plugin-mqtt","owner":"TrunkRecorder","description":"Trunk Recorder Plugin that sends current status over MQTT","archived":false,"fork":false,"pushed_at":"2025-08-07T20:17:57.000Z","size":159,"stargazers_count":6,"open_issues_count":1,"forks_count":8,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-09-06T07:57:32.509Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://trunkrecorder.com","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TrunkRecorder.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-05-30T13:00:51.000Z","updated_at":"2025-08-26T00:37:34.000Z","dependencies_parsed_at":"2024-04-09T22:12:52.775Z","dependency_job_id":"41f165d6-d70d-4df0-b3b5-e81d02b0a01b","html_url":"https://github.com/TrunkRecorder/tr-plugin-mqtt","commit_stats":null,"previous_names":["trunkrecorder/trunk-recorder-mqtt-status","trunkrecorder/tr-plugin-mqtt"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/TrunkRecorder/tr-plugin-mqtt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TrunkRecorder%2Ftr-plugin-mqtt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TrunkRecorder%2Ftr-plugin-mqtt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TrunkRecorder%2Ftr-plugin-mqtt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TrunkRecorder%2Ftr-plugin-mqtt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TrunkRecorder","download_url":"https://codeload.github.com/TrunkRecorder/tr-plugin-mqtt/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TrunkRecorder%2Ftr-plugin-mqtt/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274107983,"owners_count":25223473,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-07T02:00:09.463Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-09-07T22:47:20.550Z","updated_at":"2025-09-07T22:47:23.008Z","avatar_url":"https://github.com/TrunkRecorder.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"https://raw.githubusercontent.com/TrunkRecorder/trunk-recorder/refs/heads/master/docs/media/trunk-recorder-header.png\" width=\"75%\" height=\"75%\"\u003e\n\n[![Discord](https://raw.githubusercontent.com/TrunkRecorder/trunk-recorder/refs/heads/master/docs/media/discord.jpg)](https://discord.gg/btJAhESnks) \u0026nbsp;\u0026nbsp;\n# Trunk Recorder MQTT Plugin \u003c!-- omit from toc --\u003e\n\nThis 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.\n\nRequires trunk-recorder 5.0 or later, and Paho MQTT libraries\n\n- [Install](#install)\n- [Configure](#configure)\n- [MQTT Messages](#mqtt-messages)\n- [Trunk Recorder States](#trunk-recorder-states)\n- [MQTT Brokers](#mqtt-brokers)\n  - [Mosquitto MQTT Broker](#mosquitto-mqtt-broker)\n  - [NanoMQ](#nanomq)\n- [Docker](#docker)\n\n## Install\n\n1. **Clone Trunk Recorder** source following these [instructions](https://github.com/robotastic/trunk-recorder/blob/master/docs/Install/INSTALL-LINUX.md).\n   \n2. **Install the Paho MQTT C \u0026 C++ Libraries**.\n\n\u0026emsp; If your package manager provides recent Paho MQTT libraries, e.g:\n\n```bash\nsudo apt install libpaho-mqtt-dev libpaho-mqttpp-dev\n```\n\n\u0026emsp; If not, you may build and install these libraries from source:\n\n\u0026emsp; - _Install Paho MQTT C_\n\n```bash\ngit clone https://github.com/eclipse/paho.mqtt.c.git\ncd paho.mqtt.c\n\ncmake -Bbuild -H. -DPAHO_ENABLE_TESTING=OFF -DPAHO_BUILD_STATIC=ON  -DPAHO_WITH_SSL=ON -DPAHO_HIGH_PERFORMANCE=ON\nsudo cmake --build build/ --target install\nsudo ldconfig\n```\n\n\u0026emsp; - _Install Paho MQTT C++_\n\n```bash\ngit clone https://github.com/eclipse/paho.mqtt.cpp\ncd paho.mqtt.cpp\n\ncmake -Bbuild -H. -DPAHO_BUILD_STATIC=ON\nsudo cmake --build build/ --target install\nsudo ldconfig\n```\n\n3. **Build and install the plugin:**\n\n\u0026emsp; 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.\n\n```bash\ncd [your trunk-recorder github source directory]\ncd user_plugins\ngit clone https://github.com/taclane/trunk-recorder-mqtt-status\ncd [your trunk-recorder build directory]\nsudo make install\n```\n\n\u0026emsp; **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.\n\n## Configure\n\n**Plugin options:**\n\n| Key             | Required | Default Value        | Type       | Description                                                                                                                                                                              |\n| --------------- | :------: | -------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| 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. |\n| topic           |    ✓     |                      | string     | This is the base MQTT topic. The plugin will create subtopics for the different status messages.                                                                                         |\n| unit_topic      |          |                      | string     | Optional topic to report unit stats over MQTT.                                                                                                                                           |\n| message_topic   |          |                      | string     | Optional topic to report trunking messages over MQTT.                                                                                                                                    |\n| console_logs    |          | false                | true/false | Optional setting to report console messages over MQTT.                                                                                                                                   |\n| username        |          |                      | string     | If a username is required for the broker, add it here.                                                                                                                                   |\n| password        |          |                      | string     | If a password is required for the broker, add it here.                                                                                                                                   |\n| client_id       |          | tr-status-xxxxxxxx   | string     | Override the client_id generated for this connection to the MQTT broker.                                                                                                                 |\n| mqtt_audio      |          | false                | true/false | Optional setting to report audio in base64 and call metadata over MQTT.                                                                                                                  |\n| mqtt_audio_type |          | wav                  | string     | Control which audio files to emit.  `wav`, `m4a` (if compression enabled), `both`, `none` (only the .json)                                                                               |\n| qos             |          | 0                    | int        | Set the MQTT message [QOS level](https://www.eclipse.org/paho/files/mqttdoc/MQTTClient/html/qos.html)                                                                                    |\n\n**Trunk-Recorder options:**\n\n| Key                          | Required | Default Value               | Type   | Description                                                                                |\n| ---------------------------- | :------: | --------------------------- | ------ | ------------------------------------------------------------------------------------------ |\n| [instanceId](./config.json) |          | \u003cnobr\u003etrunk-recorder\u003c/nobr\u003e | string | Append an `instance_id` key to identify the trunk-recorder instance sending MQTT messages. |\n\n**Plugin Usage:**\n\nSee the included [config.json](./config.json) for an example how to load this plugin.\n\n```json\n    \"plugins\": [\n    {\n        \"name\": \"MQTT Status\",\n        \"library\": \"libmqtt_status_plugin.so\",\n        \"broker\": \"tcp://io.adafruit.com:1883\",\n        \"topic\": \"robotastic/feeds\",\n        \"unit_topic\": \"robotastic/units\",\n        \"username\": \"robotastic\",\n        \"password\": \"\",\n        \"console_logs\": true,\n        \"mqtt_audio\": false,\n        \"mqtt_qos\": 0,\n    }]\n```\n\nIf the plugin cannot be found, or it is being run from a different location, it may be necessary to supply the full path:\n\n```json\n        \"library\": \"/usr/local/lib/trunk-recorder/libmqtt_status_plugin.so\",\n```\n\n## MQTT Messages\n\nThe plugin will provide the following messages to the MQTT broker depending on configured topics.\n\n| Topic                   | Sub-Topic                                          | Retained | Description\\*                                                      |\n| ----------------------- | -------------------------------------------------- | :------: | ------------------------------------------------------------------ |\n| topic                   | [rates](./example_messages.md#rates)               |          | Control channel decode rates                                       |\n| topic                   | [config](./example_messages.md#config)             |    ✓     | Trunk-recorder config information                                  |\n| topic                   | [systems](./example_messages.md#systems)           |    ✓     | List of configured systems                                         |\n| topic                   | [system](./example_messages.md#system)             |          | System configuration/startup                                       |\n| topic                   | [calls_active](./example_messages.md#calls_active) |          | List of active calls, updated every second                         |\n| topic                   | [recorders](./example_messages.md#recorders)       |          | List of all recorders, updated every 3 seconds                     |\n| topic                   | [recorder](./example_messages.md#recorder)         |          | Recorder status changes                                            |\n| topic                   | [call_start](./example_messages.md#call_start)     |          | New call                                                           |\n| topic                   | [call_end](./example_messages.md#call_end)         |          | Completed call                                                     |\n| topic                   | [audio](./example_messages.md#audio)               |          | Audio and metadata of completed call                               |\n| topic/trunk_recorder    | [status](./example_messages.md#plugin_status)      |    ✓     | Plugin status, sent on startup or when the broker loses connection |\n| topic/trunk_recorder    | [console](./example_messages.md#console_logs)      |          | Trunk-Recorder console log messages                                |\n| unit_topic/shortname    | [call](./example_messages.md#call)                 |          | Channel grants                                                     |\n| unit_topic/shortname    | [end](./example_messages.md#end)                   |          | Call end unit information\\*\\*                                      |\n| unit_topic/shortname    | [on](./example_messages.md#on)                     |          | Unit registration (radio on)                                       |\n| unit_topic/shortname    | [off](./example_messages.md#off)                   |          | Unit de-registration (radio off)                                   |\n| unit_topic/shortname    | [ackresp](./example_messages.md#ackresp)           |          | Unit acknowledge response                                          |\n| unit_topic/shortname    | [join](./example_messages.md#join)                 |          | Unit group affiliation                                             |\n| unit_topic/shortname    | [data](./example_messages.md#data)                 |          | Unit data grant                                                    |\n| unit_topic/shortname    | [ans_req](./example_messages.md#ans_req)           |          | Unit answer request                                                |\n| unit_topic/shortname    | [location](./example_messages.md#location)         |          | Unit location update                                               |\n| message_topic/shortname | [messages](./example_messages.md#messages)         |          | Trunking messages                                                  |\n\n\\* Some messages have been changed for consistency. Please see links for examples and notes.  \n\\*\\* `end` is not a trunking message, but sent after trunk-recorder ends the call. This can be used to track conventional non-trunked calls.\n\n## Trunk Recorder States\n\nTrunk 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.\n\n**call_state** / **rec_state**\n| State | State Type   | Description                                                                                                |\n| :---: | ------------ | ---------------------------------------------------------------------------------------------------------- |\n|   0   | `MONITORING` | Call: Active - No recorder is assigned - See **mon_state** table                                           |\n|   1   | `RECORDING`  | Call: Active - Recorder is assigned\u003cbr\u003eRecorder: Assigned to call [Recording] - Demodulating transmissions |\n|   2   | `INACTIVE`   | Recorder: Assigned to call [Disconnecting] - Detaching from source and demodulator                         |\n|   3   | `ACTIVE`     | Recorder: Assigned to call [Tuned] - Not recording yet                                                     |\n|   4   | `IDLE`       | Recorder: Assigned to call [Squelched] - Not recording, has not timed out                                  |\n|   6   | `STOPPED`    | Recorder: Not assigned to call - Returning to `AVAILABLE` state                                            |\n|   7   | `AVAILABLE`  | Recorder: Not assigned to call - Free for use                                                              |\n|   8   | `IGNORE`     | Recorder: Assigned to call [Ignoring] - Ending call after unexpected data on the voice channel             |\n\n**mon_state**\n| State | State Type    | Description                                                                                                                      |\n| :---: | ------------- | -------------------------------------------------------------------------------------------------------------------------------- |\n|   0   | `UNSPECIFIED` | Default state                                                                                                                    |\n|   1   | `UNKNOWN_TG`  | Not recording: `recordUnknown` is `false` and talkgroup is not found in the _talkgroup.csv_ (\\*not currently implemented)        |\n|   2   | `IGNORED_TG`  | Not recording: Talkgroup has the ignore priority (`-1`) set in the _talkgroup.csv_                                               |\n|   3   | `NO_SOURCE`   | Not recording: No source exists for the requested voice frequency                                                                |\n|   4   | `NO_RECORDER` | Not recording: No recorders are available or talkgroup priority is too low                                                       |\n|   5   | `ENCRYPTED`   | Not recording: Encryption indicated by trunking messages or mode field (`E`,`DE`,`TE`) in the _talkgroup.csv_                    |\n|   6   | `DUPLICATE`   | Not recording: [multiSite] This call is a duplicate of a prior call                                                              |\n|   7   | `SUPERSEDED`  | Not recording: [multiSite] This call is a duplicate of a subsequent call with a site precedence indicated in the _talkgroup.csv_ |\n\n## MQTT Brokers\n\n### Mosquitto MQTT Broker\n\nThe [Mosquitto](https://mosquitto.org) MQTT is an easy way to have a local MQTT broker. It can be installed from a lot of package managers.\n\nThis broker does not impose a limit on the length of MQTT messages, and will handle packets up to 256 MB in size by default. \n\nStarting it on a Mac:\n\n```bash\n/opt/homebrew/sbin/mosquitto -c /opt/homebrew/etc/mosquitto/mosquitto.conf\n```\n\n### NanoMQ\n\nThe [NanoMQ](https://nanomq.io) 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. \n\nThis 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. \n\n```\n# #============================================================\n# # NanoMQ Broker\n# #============================================================\n\nmqtt {\n    property_size = 32\n    max_packet_size = 10KB\n    max_mqueue_len = 2048\n    retry_interval = 10s\n    keepalive_multiplier = 1.25\n...\n```\n[Editing `/etc/nanomq.conf`](https://nanomq.io/docs/en/latest/config-description/mqtt.html) 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.\n\n## Docker\n\nA [prebuilt docker image](https://hub.docker.com/r/thegreatcodeholio/trunk-recorder-mqtt) containing Trunk Recorder and this MQTT plugin is also available via a [community respository](https://github.com/TheGreatCodeholio/trunk-recorder-mqtt).\n\n`thegreatcodeholio/trunk-recorder-mqtt:latest`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftrunkrecorder%2Ftr-plugin-mqtt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftrunkrecorder%2Ftr-plugin-mqtt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftrunkrecorder%2Ftr-plugin-mqtt/lists"}