Update RadioLib
This commit is contained in:
parent
a8257c0cb2
commit
16bc3e2b42
46 changed files with 1102 additions and 97 deletions
141
lib/RadioLib/extras/ADSB_Monitor/ADSBMonitorServer.py
Normal file
141
lib/RadioLib/extras/ADSB_Monitor/ADSBMonitorServer.py
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import zmq
|
||||
import serial
|
||||
import threading
|
||||
import queue
|
||||
import time
|
||||
|
||||
from argparse import RawTextHelpFormatter
|
||||
|
||||
# default settings
|
||||
DEFAULT_BAUDRATE = 115200
|
||||
DEFAULT_SERVER_PORT = 30002
|
||||
|
||||
# marker to filter out ADS-B messages from the rest of the serial stream
|
||||
ADSB_MESSAGE_MARKER = '[ADS-B]'
|
||||
|
||||
class SerialToZMQBridge:
|
||||
def __init__(self, serial_port, baudrate, zmq_host="0.0.0.0", zmq_port=5555):
|
||||
self.serial_port = serial_port
|
||||
self.baudrate = baudrate
|
||||
self.zmq_host = zmq_host
|
||||
self.zmq_port = zmq_port
|
||||
|
||||
self.context = zmq.Context()
|
||||
self.socket = self.context.socket(zmq.STREAM)
|
||||
self.socket.setsockopt(zmq.LINGER, 0)
|
||||
self.socket.bind(f"tcp://{self.zmq_host}:{self.zmq_port}")
|
||||
|
||||
self.serial = serial.Serial(
|
||||
port=self.serial_port,
|
||||
baudrate=self.baudrate,
|
||||
timeout=1
|
||||
)
|
||||
|
||||
self.clients = set()
|
||||
self.serial_queue = queue.Queue()
|
||||
|
||||
self.running = True
|
||||
|
||||
def serial_reader(self):
|
||||
"""Continuously read from serial and queue messages."""
|
||||
while self.running:
|
||||
try:
|
||||
line = self.serial.readline()
|
||||
if line:
|
||||
line = line.decode(errors='ignore').strip()
|
||||
print(f"[SERIAL RX] {line}")
|
||||
|
||||
# read the ADS-B frames and add the markers expected by pyModeS
|
||||
if ADSB_MESSAGE_MARKER in line:
|
||||
msg = '*' + line.split(' ')[1].strip() + ';'
|
||||
self.serial_queue.put(msg.encode('utf-8'))
|
||||
|
||||
except Exception as e:
|
||||
print(f"Serial read error: {e}")
|
||||
time.sleep(1)
|
||||
|
||||
def run(self):
|
||||
print(f"ZMQ STREAM server listening on tcp://{self.zmq_host}:{self.zmq_port}")
|
||||
print(f"Listening to serial port {self.serial_port} @ {self.baudrate}")
|
||||
|
||||
threading.Thread(target=self.serial_reader, daemon=True).start()
|
||||
|
||||
poller = zmq.Poller()
|
||||
poller.register(self.socket, zmq.POLLIN)
|
||||
|
||||
try:
|
||||
while self.running:
|
||||
# Poll ZMQ socket
|
||||
events = dict(poller.poll(100))
|
||||
|
||||
if self.socket in events:
|
||||
identity, message = self.socket.recv_multipart()
|
||||
|
||||
if message == b'':
|
||||
# Connection event
|
||||
print(f"[ZMQ] Client connected/disconnected: {identity}")
|
||||
self.clients.add(identity)
|
||||
continue
|
||||
|
||||
print(f"[ZMQ RX] {identity}: {message.decode(errors='ignore')}")
|
||||
|
||||
# Send serial data to all connected clients
|
||||
while not self.serial_queue.empty():
|
||||
data = self.serial_queue.get()
|
||||
for client_id in list(self.clients):
|
||||
try:
|
||||
self.socket.send_multipart([client_id, data])
|
||||
print(f"[ZMQ TX] Sent to {client_id}")
|
||||
except zmq.ZMQError:
|
||||
self.clients.discard(client_id)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("Shutting down...")
|
||||
|
||||
finally:
|
||||
self.running = False
|
||||
self.serial.close()
|
||||
self.socket.close()
|
||||
self.context.term()
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(formatter_class=RawTextHelpFormatter, description='''
|
||||
RadioLib ADS-B Monitor script. Serves as server for "modeslive" live traffic decoder from pyModeS
|
||||
(https://github.com/junzis/pyModeS).
|
||||
|
||||
Depends on pyserial and pyModeS, install by:
|
||||
'python3 -m pip install pyserial pyModeS'
|
||||
|
||||
Step-by-step guide on how to use the script:
|
||||
1. Upload the ADSB_Monitor example to your Arduino board with LR2021 connected.
|
||||
2. Run the script with appropriate arguments.
|
||||
3. Run "modeslive --source net --connect localhost 30002 raw"
|
||||
''')
|
||||
parser.add_argument('port',
|
||||
type=str,
|
||||
help='COM port to connect to the device')
|
||||
parser.add_argument('--speed',
|
||||
default=DEFAULT_BAUDRATE,
|
||||
type=int,
|
||||
help=f'COM port baudrate (defaults to {DEFAULT_BAUDRATE})')
|
||||
parser.add_argument('--server-port',
|
||||
default=DEFAULT_SERVER_PORT,
|
||||
type=int,
|
||||
help=f'server port to be used by modeslive (defaults to {DEFAULT_SERVER_PORT})')
|
||||
args = parser.parse_args()
|
||||
|
||||
bridge = SerialToZMQBridge(
|
||||
serial_port=args.port,
|
||||
baudrate=args.speed,
|
||||
zmq_port=args.server_port
|
||||
)
|
||||
bridge.run()
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Loading…
Add table
Add a link
Reference in a new issue