Warning
Legal operation of this software requires an amateur radio license and a valid call sign.
Note
Star this repo to follow our progress! This code is under active development, and contributions are both welcomed and appreciated. See CONTRIBUTING.md for details.
This package provides two APRSD plugins for publishing APRS packets to MQTT:
| Plugin | Description | Output Format | Use Case |
|---|---|---|---|
| MQTTPlugin | Publishes decoded APRS packets | JSON | Easy integration with home automation, dashboards, databases |
| MQTTRawPlugin | Publishes raw APRS-IS strings | Plain text | Maximum throughput, custom parsing, low latency |
Both plugins share the same MQTT connection configuration. Choose the one that best fits your use case - they are mutually exclusive (use one or the other, not both).
- Two Operating Modes: Choose between decoded JSON or raw APRS-IS string publishing
- MQTT Publishing: Automatically publishes all received APRS packets to a configured MQTT topic
- JSON Format: Decoded plugin publishes packets as JSON for easy consumption by other systems
- Raw Mode: Maximum throughput with zero parsing overhead - subscriber handles all decoding
- Freethreaded Python Support: Compatible with both standard and freethreaded Python builds
- Configurable Broker: Connect to any MQTT broker (local or remote)
- Authentication Support: Optional username/password authentication for MQTT broker
- Real-time Integration: Enables real-time APRS data streaming to MQTT subscribers
aprsd >= 3.0.0- A running APRSD instance
- Access to an MQTT broker (Mosquitto, HiveMQ, EMQX, etc.)
You can install APRSD MQTT Plugin via pip from PyPI:
$ pip install aprsd-mqtt-pluginOr using uv:
$ uv pip install aprsd-mqtt-pluginBefore using the MQTT plugin, you need to configure it in your APRSD configuration file. Generate a sample configuration file if you haven't already:
$ aprsd sample-configThis will create a configuration file at ~/.config/aprsd/aprsd.conf (or aprsd.yml).
| Option | Default | Description |
|---|---|---|
enabled |
False |
Enable the MQTT plugin |
host_ip |
(required) | MQTT broker hostname or IP address |
host_port |
1883 |
MQTT broker port |
user |
(optional) | MQTT username for authentication |
password |
(optional) | MQTT password for authentication |
topic |
aprsd/packet |
Topic for decoded JSON packets (MQTTPlugin) |
raw_topic |
aprsd/raw |
Topic for raw APRS-IS strings (MQTTRawPlugin) |
[aprsd_mqtt_plugin]
# Enable the MQTT plugin (default: False)
enabled = True
# MQTT broker hostname or IP address (required)
host_ip = mqtt.example.com
# MQTT broker port (default: 1883)
host_port = 1883
# MQTT topic for decoded JSON packets (default: aprsd/packet)
topic = aprsd/packets
# MQTT topic for raw APRS-IS strings (default: aprsd/raw)
raw_topic = aprsd/raw
# Optional: MQTT username for authentication
user = mqtt_user
# Optional: MQTT password for authentication
password = mqtt_passwordThe MQTTPlugin receives decoded APRS packets from APRSD, serializes them to JSON, and publishes them to the configured topic.
Add to your APRSD configuration:
[aprsd]
enabled_plugins = aprsd_mqtt_plugin.MQTTPlugin- APRSD receives and decodes APRS packets from APRS-IS
- MQTTPlugin receives the decoded packet objects via APRSD's plugin hook
- Packets are serialized to JSON and published to the
topic - Maintains a persistent connection to the MQTT broker
Packets are published as JSON with the following structure:
{
"from": "CALLSIGN",
"to": "DESTINATION",
"message_text": "Message content",
"path": ["WIDE1-1", "WIDE2-2"],
"timestamp": "2024-01-01T12:00:00"
}Note: Additional fields may be present depending on packet type (position, weather, telemetry, etc.).
$ mosquitto_sub -h localhost -t aprsd/packetsThe MQTTRawPlugin consumes raw APRS-IS strings directly from APRSD's packet queue and publishes them without any decoding or transformation. This provides maximum throughput for applications that need to handle parsing themselves.
Add to your APRSD configuration:
[aprsd]
enabled_plugins = aprsd_mqtt_plugin.MQTTRawPlugin- APRSD receives raw APRS-IS strings from the network
- MQTTRawPlugin pulls raw strings directly from the packet queue (before decoding)
- Raw strings are published as-is to the
raw_topic - Subscriber is responsible for parsing the APRS protocol
Raw packets are published as plain text strings exactly as received from APRS-IS:
N0CALL>APRS,TCPIP*,qAC,T2TEXAS:>Hello World
WB4BOR-9>APTT4,WIDE1-1,WIDE2-1,qAR,W4KEL-1:!3400.00N/08400.00W>000/000
- Maximum throughput - No CPU cycles spent on decoding
- Custom parsing - You need to parse packets differently than APRSD does
- Minimal latency - Fastest path from APRS-IS to your application
- Data archival - Store original APRS-IS format for later processing
$ mosquitto_sub -h localhost -t aprsd/rawAfter starting APRSD, check the logs for messages like:
INFO: Connecting to mqtt://localhost:1883
INFO: Connected to mqtt://localhost:1883/aprsd/packets (0)
For MQTTRawPlugin:
INFO: MQTTRawPlugin Publishing packet (200) to mqtt://localhost:1883/aprsd/raw
mqtt:
sensor:
- name: "APRS Packet"
state_topic: "aprsd/packets"
value_template: "{{ value_json.message_text }}"Decoded mode: Connect an MQTT input node to aprsd/packets and parse the JSON payload.
Raw mode: Connect an MQTT input node to aprsd/raw and use a function node to parse the raw APRS string.
Subscribe to either topic and process packets in your application:
import paho.mqtt.client as mqtt
import json
def on_message(client, userdata, msg):
if msg.topic == "aprsd/packets":
packet = json.loads(msg.payload)
print(f"From: {packet['from']}, Message: {packet.get('message_text', '')}")
elif msg.topic == "aprsd/raw":
raw = msg.payload.decode()
print(f"Raw: {raw}")
client = mqtt.Client()
client.on_message = on_message
client.connect("localhost", 1883)
client.subscribe("aprsd/#")
client.loop_forever()For more details, see the Command-line Reference.
Contributions are very welcome. To learn more, see the Contributor Guide.
Distributed under the terms of the Apache Software License 2.0 license, APRSD MQTT Plugin is free and open source software.
If you encounter any problems, please file an issue along with a detailed description.
This project was generated from @hemna's APRSD Plugin Python Cookiecutter template.