From 205725872a753a7004760aa40635ebd8c2c3d695 Mon Sep 17 00:00:00 2001 From: Junzi Sun Date: Sat, 23 Jun 2018 15:19:29 +0200 Subject: [PATCH] update pmslive and tcpclient, add support for AVR. --- README.rst | 13 ++++-- .../extra/{beastclient.py => tcpclient.py} | 45 ++++++++++++++++--- pyModeS/streamer/pmslive | 20 +++++---- 3 files changed, 61 insertions(+), 17 deletions(-) rename pyModeS/extra/{beastclient.py => tcpclient.py} (82%) diff --git a/README.rst b/README.rst index 97a2f44..4b085c3 100644 --- a/README.rst +++ b/README.rst @@ -66,13 +66,20 @@ To install latest development version (dev-2.0) from the GitHub: -Live view traffic +Live view traffic (pmslive) ---------------------------------------------------- -Supports Mode-S Beast raw stream +Supports **Mode-S Beast** and **AVR** raw stream :: - pmslive --server URL/IP --port PORT --lat0 RECEIVER_LAT --lon0 RECEIVER_LON + pmslive --server [server_address] --port [tcp_port] --rawtype [beast_or_avr] --latlon [lat] [lon] + + Arguments: + -h, --help show this help message and exit + --server SERVER server address or IP + --port PORT raw data port + --rawtype RAWTYPE beast or avr + --latlon LAT LON receiver position diff --git a/pyModeS/extra/beastclient.py b/pyModeS/extra/tcpclient.py similarity index 82% rename from pyModeS/extra/beastclient.py rename to pyModeS/extra/tcpclient.py index 370a631..6510325 100644 --- a/pyModeS/extra/beastclient.py +++ b/pyModeS/extra/tcpclient.py @@ -2,6 +2,7 @@ Stream beast raw data from a TCP server, convert to mode-s messages ''' from __future__ import print_function, division +import os import sys import socket import time @@ -13,12 +14,15 @@ else: PY_VERSION = 2 class BaseClient(Thread): - def __init__(self, host, port): + def __init__(self, host, port, rawtype): Thread.__init__(self) self.host = host self.port = port self.buffer = [] - + self.rawtype = rawtype + if self.rawtype not in ['avr', 'beast']: + print("rawtype must be either avr or beast") + os._exit(1) def connect(self): while True: @@ -33,6 +37,33 @@ class BaseClient(Thread): print("Socket connection error: %s. reconnecting..." % err) time.sleep(3) + + def read_avr_buffer(self): + # -- testing -- + # for b in self.buffer: + # print(chr(b), b) + + # Append message with 0-9,A-F,a-f, until stop sign + + messages = [] + + msg_stop = False + for b in self.buffer: + if b == 59: + msg_stop = True + ts = time.time() + messages.append([self.current_msg, ts]) + if b == 42: + msg_stop = False + self.current_msg = '' + + if (not msg_stop) and (48<=b<=57 or 65<=b<=70 or 97<=b<=102): + self.current_msg = self.current_msg + chr(b) + + self.buffer = [] + + return messages + def read_beast_buffer(self): ''' "1" : 6 byte MLAT timestamp, 1 byte signal level, @@ -91,6 +122,8 @@ class BaseClient(Thread): # extract messages messages = [] for mm in messages_mlat: + ts = time.time() + msgtype = mm[0] # print(''.join('%02X' % i for i in mm)) @@ -108,11 +141,10 @@ class BaseClient(Thread): # incomplete message continue - ts = time.time() - messages.append([msg, ts]) return messages + def handle_messages(self, messages): """re-implement this method to handle the messages""" for msg, t in messages: @@ -136,7 +168,10 @@ class BaseClient(Thread): # continue # -- Removed!! Cause delay in low data rate scenario -- - messages = self.read_beast_buffer() + if self.rawtype == 'beast': + messages = self.read_beast_buffer() + elif self.rawtype == 'avr': + messages = self.read_avr_buffer() if not messages: continue diff --git a/pyModeS/streamer/pmslive b/pyModeS/streamer/pmslive index 7221825..463a74e 100755 --- a/pyModeS/streamer/pmslive +++ b/pyModeS/streamer/pmslive @@ -7,7 +7,7 @@ import argparse import curses from threading import Lock import pyModeS as pms -from pyModeS.extra.beastclient import BaseClient +from pyModeS.extra.tcpclient import BaseClient from pyModeS.streamer.stream import Stream from pyModeS.streamer.screen import Screen @@ -19,19 +19,21 @@ COMMB_TS = [] parser = argparse.ArgumentParser() parser.add_argument('--server', help='server address or IP', required=True) -parser.add_argument('--port', help='Raw beast port', required=True) -parser.add_argument('--lat0', help='Latitude of receiver', required=True) -parser.add_argument('--lon0', help='Longitude of receiver', required=True) +parser.add_argument('--port', help='raw data port', required=True) +parser.add_argument('--rawtype', help='beast or avr', required=True) +parser.add_argument('--latlon', help='receiver position', nargs=2, metavar=('LAT', 'LON'), required=True) args = parser.parse_args() SERVER = args.server PORT = int(args.port) -LAT0 = float(args.lat0) # 51.9899 for TU Delft -LON0 = float(args.lon0) # 4.3754 +RAWTYPE = args.rawtype +LAT0 = float(args.latlon[0]) +LON0 = float(args.latlon[1]) + class ModesClient(BaseClient): - def __init__(self, host, port): - super(ModesClient, self).__init__(host, port) + def __init__(self, host, port, rawtype): + super(ModesClient, self).__init__(host, port, rawtype) def handle_messages(self, messages): local_buffer_adsb_msg = [] @@ -66,7 +68,7 @@ class ModesClient(BaseClient): # redirect all stdout to null, avoiding messing up with the screen sys.stdout = open(os.devnull, 'w') -client = ModesClient(host=SERVER, port=PORT) +client = ModesClient(host=SERVER, port=PORT, rawtype=RAWTYPE) client.daemon = True client.start()