202 lines
5.2 KiB
Python
Executable File
202 lines
5.2 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
from __future__ import print_function, division
|
|
import os
|
|
import sys
|
|
import time
|
|
import argparse
|
|
import curses
|
|
from threading import Lock
|
|
import pyModeS as pms
|
|
from pyModeS.extra.tcpclient import BaseClient
|
|
from pyModeS.extra.rtlreader import RtlReader
|
|
from pyModeS.streamer.stream import Stream
|
|
from pyModeS.streamer.screen import Screen
|
|
|
|
LOCK = Lock()
|
|
ADSB_MSG = []
|
|
ADSB_TS = []
|
|
COMMB_MSG = []
|
|
COMMB_TS = []
|
|
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument(
|
|
"--source", help="rtlsdr or tcp", required=True, default="tcp"
|
|
)
|
|
parser.add_argument("--server", help="server address or IP", default=None)
|
|
parser.add_argument("--port", help="raw data port", default=None)
|
|
parser.add_argument("--rawtype", help="beast, avr or skysense", default=None)
|
|
parser.add_argument(
|
|
"--latlon",
|
|
help="receiver position",
|
|
nargs=2,
|
|
metavar=("LAT", "LON"),
|
|
required=True,
|
|
)
|
|
parser.add_argument(
|
|
"--show-uncertainty",
|
|
dest="uncertainty",
|
|
help="display uncertaint values, default off",
|
|
action="store_true",
|
|
required=False,
|
|
default=False,
|
|
)
|
|
parser.add_argument(
|
|
"--dumpto",
|
|
help="folder to dump decoded output",
|
|
required=False,
|
|
default=None,
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
SOURCE = args.source
|
|
SERVER = args.server
|
|
PORT = args.port
|
|
RAWTYPE = args.rawtype
|
|
LAT0 = float(args.latlon[0])
|
|
LON0 = float(args.latlon[1])
|
|
UNCERTAINTY = args.uncertainty
|
|
DUMPTO = args.dumpto
|
|
|
|
if SOURCE == "rtlsdr":
|
|
pass
|
|
elif SOURCE == "tcp":
|
|
if SERVER is None:
|
|
print("You must specify the server for TCP source.")
|
|
sys.exit(1)
|
|
if PORT is None:
|
|
print("You must specify the port for TCP source.")
|
|
sys.exit(1)
|
|
if RAWTYPE is None:
|
|
print("You must specify the rawtype for TCP source.")
|
|
sys.exit(1)
|
|
else:
|
|
print("Source must be rtlsdr or tcp.")
|
|
sys.exit(1)
|
|
|
|
if DUMPTO is not None:
|
|
# append to current folder except root is given
|
|
if DUMPTO[0] != "/":
|
|
DUMPTO = os.getcwd() + "/" + DUMPTO
|
|
|
|
if not os.path.isdir(DUMPTO):
|
|
print("Error: dump folder (%s) does not exist" % DUMPTO)
|
|
sys.exit(1)
|
|
|
|
|
|
class ModesClient(BaseClient):
|
|
def __init__(self, host, port, rawtype):
|
|
super(ModesClient, self).__init__(host, port, rawtype)
|
|
|
|
def handle_messages(self, messages):
|
|
local_buffer_adsb_msg = []
|
|
local_buffer_adsb_ts = []
|
|
local_buffer_ehs_msg = []
|
|
local_buffer_ehs_ts = []
|
|
|
|
for msg, t in messages:
|
|
if len(msg) < 28: # only process long messages
|
|
continue
|
|
|
|
df = pms.df(msg)
|
|
|
|
if df == 17 or df == 18:
|
|
local_buffer_adsb_msg.append(msg)
|
|
local_buffer_adsb_ts.append(t)
|
|
elif df == 20 or df == 21:
|
|
local_buffer_ehs_msg.append(msg)
|
|
local_buffer_ehs_ts.append(t)
|
|
else:
|
|
continue
|
|
|
|
LOCK.acquire()
|
|
ADSB_MSG.extend(local_buffer_adsb_msg)
|
|
ADSB_TS.extend(local_buffer_adsb_ts)
|
|
COMMB_MSG.extend(local_buffer_ehs_msg)
|
|
COMMB_TS.extend(local_buffer_ehs_ts)
|
|
LOCK.release()
|
|
|
|
|
|
class ModesRtlReader(RtlReader):
|
|
"""docstring for ModesRtlReader."""
|
|
|
|
def __init__(self):
|
|
super(ModesRtlReader, self).__init__()
|
|
|
|
def handle_messages(self, messages):
|
|
local_buffer_adsb_msg = []
|
|
local_buffer_adsb_ts = []
|
|
local_buffer_ehs_msg = []
|
|
local_buffer_ehs_ts = []
|
|
|
|
for msg, t in messages:
|
|
if len(msg) < 28: # only process long messages
|
|
continue
|
|
|
|
df = pms.df(msg)
|
|
|
|
if df == 17 or df == 18:
|
|
local_buffer_adsb_msg.append(msg)
|
|
local_buffer_adsb_ts.append(t)
|
|
elif df == 20 or df == 21:
|
|
local_buffer_ehs_msg.append(msg)
|
|
local_buffer_ehs_ts.append(t)
|
|
else:
|
|
continue
|
|
|
|
LOCK.acquire()
|
|
ADSB_MSG.extend(local_buffer_adsb_msg)
|
|
ADSB_TS.extend(local_buffer_adsb_ts)
|
|
COMMB_MSG.extend(local_buffer_ehs_msg)
|
|
COMMB_TS.extend(local_buffer_ehs_ts)
|
|
# print(len(ADSB_MSG))
|
|
# print(len(COMMB_MSG))
|
|
LOCK.release()
|
|
|
|
|
|
# redirect all stdout to null, avoiding messing up with the screen
|
|
sys.stdout = open(os.devnull, "w")
|
|
|
|
if SOURCE == "tcp":
|
|
client = ModesClient(host=SERVER, port=PORT, rawtype=RAWTYPE)
|
|
client.daemon = True
|
|
client.start()
|
|
elif SOURCE == "rtlsdr":
|
|
rtl = ModesRtlReader()
|
|
# rtl.debug = True
|
|
rtl.daemon = True
|
|
rtl.start()
|
|
|
|
stream = Stream(lat0=LAT0, lon0=LON0, dumpto=DUMPTO)
|
|
|
|
try:
|
|
screen = Screen(uncertainty=UNCERTAINTY)
|
|
screen.daemon = True
|
|
screen.start()
|
|
|
|
while True:
|
|
if len(ADSB_MSG) > 1:
|
|
LOCK.acquire()
|
|
stream.process_raw(ADSB_TS, ADSB_MSG, COMMB_TS, COMMB_MSG)
|
|
ADSB_MSG = []
|
|
ADSB_TS = []
|
|
COMMB_MSG = []
|
|
COMMB_TS = []
|
|
LOCK.release()
|
|
|
|
acs = stream.get_aircraft()
|
|
try:
|
|
screen.update_data(acs)
|
|
screen.update()
|
|
time.sleep(1)
|
|
except KeyboardInterrupt:
|
|
raise
|
|
except:
|
|
continue
|
|
|
|
except KeyboardInterrupt:
|
|
sys.exit(0)
|
|
|
|
finally:
|
|
curses.endwin()
|