You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

264 lines
7.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# MQTT Support for DStarRepeater
DStarRepeater can publish log messages and repeater status to an MQTT
broker, providing live telemetry for dashboards, home-automation systems,
or any MQTT client.
**MQTT is enabled by default.** To build without MQTT support, use `make MQTT=0`.
When built without MQTT, no MQTT code is compiled in and `libmosquitto` is not required.
A full JSON schema for all MQTT messages is available in [schema.json](schema.json).
## Building
MQTT is on by default. Install `libmosquitto-dev` before building:
```bash
sudo apt-get install libmosquitto-dev
make
```
To build without MQTT:
```bash
make MQTT=0
```
All MQTT code paths are guarded by `#if defined(MQTT)` / `#endif`.
## Configuration
MQTT settings are in the `[MQTT]` section of the INI config file:
```ini
[MQTT]
Host=127.0.0.1
Port=1883
Auth=0
Username=
Password=
Keepalive=60
Name=dstar-repeater
```
| Key | Default | Description |
|-----|---------|-------------|
| `Host` | `127.0.0.1` | MQTT broker hostname or IP address. Empty to disable. |
| `Port` | `1883` | MQTT broker port. |
| `Auth` | `0` | `1` = authenticate with username/password. |
| `Username` | *(empty)* | Broker username (when Auth=1). |
| `Password` | *(empty)* | Broker password (when Auth=1). |
| `Keepalive` | `60` | Keepalive interval in seconds. |
| `Name` | `dstar-repeater` | Client name and MQTT topic prefix. |
The MQTT log level is configured in the `[Log]` section:
```ini
[Log]
MQTTLevel=2
```
If `Host` is left empty, MQTT is disabled at runtime even when compiled in.
See [CONFIGURATION.md](CONFIGURATION.md) for the full configuration reference.
## MQTT Topics
All topics are prefixed with the `Name` value. With the default `dstar-repeater`:
### `dstar-repeater/log`
Timestamped log messages, filtered by severity. The format matches the
log file output:
```
M: 2026-03-19 14:22:01: Starting D-Star Repeater - 20260319
M: 2026-03-19 14:22:01: Using Linux 6.1.21-v8+ on aarch64
M: 2026-03-19 14:22:01: Callsign set to "GB7XX B", gateway set to "GB7XX G"
I: 2026-03-19 14:22:01: MQTT connected to 127.0.0.1:1883 as dstar-repeater
```
Log levels (highest to lowest):
| Letter | Level | Numeric |
|--------|-------|---------|
| `F` | Fatal | 6 |
| `E` | Error | 5 |
| `W` | Warning | 4 |
| `I` | Info | 3 |
| `M` | Message | 2 |
| `D` | Debug | 1 |
Only messages at or above the configured `MQTTLevel` are published.
The default is **2** (Message level), matching MMDVMHost behaviour.
### `dstar-repeater/status`
A JSON object published once per second with the current repeater state:
**Idle (no traffic):**
```json
{
"myCall1": "",
"myCall2": "",
"yourCall": "",
"rptCall1": "",
"rptCall2": "",
"tx": false,
"rxState": "listening",
"rptState": "listening",
"ber": 0.0,
"text": "",
"status1": "",
"status2": "",
"status3": "",
"status4": "",
"status5": ""
}
```
**During an RF transmission:**
```json
{
"myCall1": "MW0MWZ ",
"myCall2": " ",
"yourCall": "CQCQCQ ",
"rptCall1": "GB7XX B",
"rptCall2": "GB7XX G",
"tx": true,
"rxState": "process_data",
"rptState": "valid",
"ber": 1.3,
"text": "Hello from Pi-Star",
"status1": "",
"status2": "",
"status3": "",
"status4": "",
"status5": ""
}
```
#### Status Field Reference
| Field | Type | Description |
|-------|------|-------------|
| `myCall1` | string | Transmitting station's callsign (8 chars, space-padded) |
| `myCall2` | string | Transmitting station's short suffix (4 chars) |
| `yourCall` | string | Destination callsign (`CQCQCQ` for CQ calls) |
| `rptCall1` | string | Repeater callsign with module letter |
| `rptCall2` | string | Gateway callsign |
| `tx` | boolean | `true` when the repeater is transmitting |
| `rxState` | string | `listening`, `process_data`, or `process_slow_data` |
| `rptState` | string | See repeater states below |
| `ber` | float | Bit Error Rate as a percentage (0.0 when idle) |
| `text` | string | Slow-data text message (if any) |
| `status1``status5` | string | User-configured status text messages |
#### Repeater States (`rptState`)
| Value | Meaning |
|-------|---------|
| `listening` | Idle, waiting for traffic |
| `valid` | Receiving valid RF traffic |
| `valid_wait` | Valid RF ended, waiting for ack window |
| `invalid` | Receiving RF that failed validation |
| `invalid_wait` | Invalid RF ended, waiting |
| `timeout` | Transmission timed out |
| `timeout_wait` | Timeout ended, waiting |
| `network` | Receiving traffic from the gateway |
| `shutdown` | Repeater is shut down |
### `dstar-repeater/json`
Event-driven JSON messages published at D-Star state transitions, in the
format expected by [Display-Driver](https://github.com/MW0MWZ/Display-Driver).
This means DStarRepeater can drive an OLED/TFT display via MQTT with no
modifications to Display-Driver.
**RF transmission starts:**
```json
{"D-Star":{"action":"start","source_cs":"MW0MWZ ","source_ext":" ","destination_cs":"CQCQCQ ","reflector":"GB7XX G","source":"rf"}}
```
**Transmission ends normally:**
```json
{"D-Star":{"action":"end"}}
```
**Transmission lost (watchdog timeout):**
```json
{"D-Star":{"action":"lost"}}
```
**Return to idle:**
```json
{"MMDVM":{"mode":"idle"}}
```
**BER update (once per second during active RF):**
```json
{"BER":{"mode":"D-Star","value":1.3}}
```
**RSSI update (DVAP modem, once per second during active RF):**
```json
{"RSSI":{"mode":"D-Star","value":-85}}
```
#### Display-Driver Compatibility
These messages use the exact same JSON keys and structure that
Display-Driver expects. Configure Display-Driver to subscribe to
`dstar-repeater/json`.
| Top-level key | Display-Driver parser | When published |
|---------------|----------------------|----------------|
| `D-Star` | `parseDStar()` | Transmission start, end, or lost |
| `BER` | `parseBER()` | Once per second during active RF |
| `RSSI` | `parseRSSI()` | Once per second during active RF (DVAP only) |
| `MMDVM` | `parseMMDVM()` | On return to idle |
## Subscribing to MQTT Output
Use any MQTT client to subscribe:
```bash
# Follow all DStarRepeater topics:
mosquitto_sub -h 127.0.0.1 -t "dstar-repeater/#"
# Log messages only:
mosquitto_sub -h 127.0.0.1 -t "dstar-repeater/log"
# Pretty-print status with jq:
mosquitto_sub -h 127.0.0.1 -t "dstar-repeater/status" | jq .
```
## Comparison with MMDVMHost
This implementation follows MMDVMHost's MQTT conventions:
- Same `CMQTTConnection` class wrapping `libmosquitto`
- Same topic-prefix convention (`{name}/topic`)
- Same INI-style `[MQTT]` configuration section
- Same log-level filtering and format
- Same PID-based client ID scheme
- Same QoS default (EXACTLY_ONCE / QoS 2)
DStarRepeater is a **publish-only** client — it does not subscribe to
any MQTT topics or accept remote commands via MQTT.
## Troubleshooting
**"Unable to start MQTT connection"** in logs:
- Check that Mosquitto (or another MQTT broker) is running
- Verify credentials if `Auth=1`
- Check firewall rules if connecting to a remote broker
**No messages appearing:**
- Confirm the binary was built with MQTT support (default: on)
- Check that `Host` is not empty in the `[MQTT]` section
- Verify the broker: `mosquitto_pub -h 127.0.0.1 -t test -m hello`
**Log messages missing but status works:**
- The `MQTTLevel` in `[Log]` may be filtering them. Default is 2 (Message).

Powered by TurnKey Linux.