1

aprs-mqtt bridge

This commit is contained in:
Evan Pratten 2024-11-21 19:48:56 -05:00
parent c85bbc0107
commit e62ae04a21
3 changed files with 87 additions and 0 deletions

View File

@ -0,0 +1,13 @@
FROM python:3.13
# External config
ENV MQTT_HOST=
# Dependencies
RUN pip install paho-mqtt
# The script itself
COPY ./scripts/aprs-to-mqtt /aprs-to-mqtt.py
# Run config
CMD ["sh", "-c", "python /aprs-to-mqtt.py $MQTT_HOST"]

View File

@ -25,5 +25,14 @@ services:
dockerfile: docker/containers/pskreporter-to-mqtt.dockerfile
restart: unless-stopped
env_file: .env
environment:
- MQTT_HOST=${MQTT_HOST}
aprs_to_mqtt:
build:
context: ../..
dockerfile: docker/containers/aprs-to-mqtt.dockerfile
restart: unless-stopped
env_file: .env
environment:
- MQTT_HOST=${MQTT_HOST}

65
scripts/aprs-to-mqtt Executable file
View File

@ -0,0 +1,65 @@
#! /usr/bin/env python3
import argparse
import sys
import logging
import socket
import re
import json
import paho.mqtt.client as mqtt # pip install paho-mqtt
from datetime import datetime, UTC
logger = logging.getLogger(__name__)
def main() -> int:
# Handle program arguments
ap = argparse.ArgumentParser(prog='aprs-to-mqtt', description='Reflects APRS spots to an MQTT broker')
ap.add_argument("mqtt_broker", help="MQTT broker to connect to")
ap.add_argument('-v', '--verbose', help='Enable verbose logging', action='store_true')
args = ap.parse_args()
# Configure logging
logging.basicConfig(
level=logging.DEBUG if args.verbose else logging.INFO,
format='%(levelname)s: %(message)s',
)
# Connect to the MQTT broker
mqtt_client = mqtt.Client()
mqtt_client.connect(args.mqtt_broker)
# Connect to APRS-IS
aprs_socket = socket.create_connection(('rotate.aprs.net', 10152))
# Authenticate with the core server
aprs_socket.sendall(b'user n0call pass -1\r\n')
# Handle incoming packets
buffer = b''
while True:
# Read incoming packet (may contain multiple actual APRS packets)
data = aprs_socket.recv(1024)
if not data:
break
# Append to buffer
buffer += data
# Split the packet into aprs packets
if b'\r\n' in buffer:
chunks = buffer.splitlines()
buffer = chunks.pop() # Store the un-finished chunk for later
for aprs_packet in chunks:
if aprs_packet.startswith(b'#'):
continue
# Try to chop off the sender callsign
sender = aprs_packet.split(b'>', 1)[0]
# Send over MQTT
logger.debug(f"Received APRS packet from {sender.decode('utf-8').upper()}: {aprs_packet}")
mqtt_client.publish(f"radio/aprs/raw/{sender.decode('utf-8').upper()}", aprs_packet)
return 0
if __name__ == "__main__":
sys.exit(main())