aprs-mqtt bridge
This commit is contained in:
parent
c85bbc0107
commit
e62ae04a21
13
docker/containers/aprs-to-mqtt.dockerfile
Normal file
13
docker/containers/aprs-to-mqtt.dockerfile
Normal 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"]
|
@ -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
65
scripts/aprs-to-mqtt
Executable 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())
|
Loading…
x
Reference in New Issue
Block a user