diff --git a/pyModeS/decoder/adsb.py b/pyModeS/decoder/adsb.py index dacce31..5a72a35 100644 --- a/pyModeS/decoder/adsb.py +++ b/pyModeS/decoder/adsb.py @@ -452,6 +452,8 @@ def sil(msg, version): elif tc == 31: sil = common.bin2int(msg[82:84]) + sil_sup = None + if version == 2: if version == 29: sil_sup = common.bin2int(msgbin[39]) diff --git a/pyModeS/streamer/__init__.py b/pyModeS/streamer/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pyModeS/streamer/pmstream.py b/pyModeS/streamer/pmstream.py index 450d4e9..8b7e14b 100644 --- a/pyModeS/streamer/pmstream.py +++ b/pyModeS/streamer/pmstream.py @@ -14,8 +14,8 @@ from pyModeS.streamer.screen import Screen LOCK = Lock() ADSB_MSG = [] ADSB_TS = [] -EHS_MSG = [] -EHS_TS = [] +COMMB_MSG = [] +COMMB_TS = [] parser = argparse.ArgumentParser() parser.add_argument('--server', help='server address or IP', required=True) @@ -58,11 +58,12 @@ class ModesClient(BaseClient): LOCK.acquire() ADSB_MSG.extend(local_buffer_adsb_msg) ADSB_TS.extend(local_buffer_adsb_ts) - EHS_MSG.extend(local_buffer_ehs_msg) - EHS_TS.extend(local_buffer_ehs_ts) + COMMB_MSG.extend(local_buffer_ehs_msg) + COMMB_TS.extend(local_buffer_ehs_ts) LOCK.release() +# redirect all stdout to null, avoiding messing up with the screen sys.stdout = open(os.devnull, 'w') client = ModesClient(host=SERVER, port=PORT) @@ -79,11 +80,11 @@ try: while True: if len(ADSB_MSG) > 200: LOCK.acquire() - stream.process_raw(ADSB_TS, ADSB_MSG, EHS_TS, EHS_MSG) + stream.process_raw(ADSB_TS, ADSB_MSG, COMMB_TS, COMMB_MSG) ADSB_MSG = [] ADSB_TS = [] - EHS_MSG = [] - EHS_TS = [] + COMMB_MSG = [] + COMMB_TS = [] LOCK.release() acs = stream.get_aircraft() diff --git a/pyModeS/streamer/screen.py b/pyModeS/streamer/screen.py index cc45e38..2992425 100644 --- a/pyModeS/streamer/screen.py +++ b/pyModeS/streamer/screen.py @@ -4,7 +4,24 @@ import numpy as np import time from threading import Thread -COLUMNS = ['lat', 'lon', 'alt', 'gs', 'tas', 'ias', 'mach', 'roc', 'trk', 'hdg', 't'] +COLUMNS = [ + ('lat', 10), + ('lon', 10), + ('alt', 7), + ('gs', 5), + ('tas', 5), + ('ias', 5), + ('mach', 7), + ('roc', 7), + ('trk', 10), + ('hdg', 10), + ('ver', 4), + ('NIC', 5), + ('NACv', 5), + ('NACp', 5), + ('SIL', 5), + ('updated', 12), +] class Screen(Thread): def __init__(self): @@ -44,10 +61,10 @@ class Screen(Thread): row = 1 - header = 'icao' - for c in COLUMNS: + header = ' icao' + for c, cw in COLUMNS: c = 'updated' if c=='t' else c - header += '%10s' % c + header += (cw-len(c))*' ' + c if len(header) > self.scr_w - 2: header = header[:self.scr_w-3] + '>' @@ -74,19 +91,15 @@ class Screen(Thread): line += icao - for c in COLUMNS: - - if c == 't': - val = str(int(ac[c])) - line += '%12s' % val - else: - val = '' if ac[c] is None else ac[c] - line += '%10s' % val + for c, cw in COLUMNS: + val = '' if ac[c] is None else ac[c] + val_str = str(val) + line += (cw-len(val_str))*' ' + val_str if len(line) > self.scr_w - 2: line = line[:self.scr_w-3] + '>' - if self.lock_icao == icao: + if (icao is not None) and (self.lock_icao == icao): self.screen.addstr(row, 1, line, curses.A_STANDOUT) elif row == self.y: self.screen.addstr(row, 1, line, curses.A_BOLD) diff --git a/pyModeS/streamer/stream.py b/pyModeS/streamer/stream.py index 3dee46d..728815d 100644 --- a/pyModeS/streamer/stream.py +++ b/pyModeS/streamer/stream.py @@ -1,7 +1,7 @@ from __future__ import absolute_import, print_function, division import numpy as np import time -from pyModeS.decoder import adsb, ehs +import pyModeS as pms class Stream(): def __init__(self, lat0, lon0): @@ -18,8 +18,8 @@ class Stream(): self.cache_timeout = 60 # seconds - def process_raw(self, adsb_ts, adsb_msgs, ehs_ts, ehs_msgs, tnow=None): - """process a chunk of adsb and ehs messages recieved in the same + def process_raw(self, adsb_ts, adsb_msgs, commb_ts, commb_msgs, tnow=None): + """process a chunk of adsb and commb messages recieved in the same time period. """ if tnow is None: @@ -31,11 +31,12 @@ class Stream(): # process adsb message for t, msg in zip(adsb_ts, adsb_msgs): - icao = adsb.icao(msg) - tc = adsb.typecode(msg) + icao = pms.icao(msg) + tc = pms.adsb.typecode(msg) if icao not in self.acs: self.acs[icao] = { + 'updated': None, 'lat': None, 'lon': None, 'alt': None, @@ -46,20 +47,20 @@ class Stream(): 'ias': None, 'mach': None, 'hdg': None, - 'adsb_version' : None, - 'nic_s' : None, - 'nic_a' : None, - 'nic_b' : None, - 'nic_c' : None + 'ver' : None, + 'NIC' : None, + 'NACp' : None, + 'NACv' : None, + 'SIL' : None } - self.acs[icao]['t'] = t + self.acs[icao]['updated'] = int(t) if 1 <= tc <= 4: - self.acs[icao]['callsign'] = adsb.callsign(msg) + self.acs[icao]['callsign'] = pms.adsb.callsign(msg) if (5 <= tc <= 8) or (tc == 19): - vdata = adsb.velocity(msg) + vdata = pms.adsb.velocity(msg) if vdata is None: continue @@ -75,7 +76,7 @@ class Stream(): self.acs[icao]['tv'] = t if (5 <= tc <= 18): - oe = adsb.oe_flag(msg) + oe = pms.adsb.oe_flag(msg) self.acs[icao][oe] = msg self.acs[icao]['t'+str(oe)] = t @@ -83,21 +84,21 @@ class Stream(): # use single message decoding rlat = self.acs[icao]['lat'] rlon = self.acs[icao]['lon'] - latlon = adsb.position_with_ref(msg, rlat, rlon) + latlon = pms.adsb.position_with_ref(msg, rlat, rlon) elif ('t0' in self.acs[icao]) and ('t1' in self.acs[icao]) and \ (abs(self.acs[icao]['t0'] - self.acs[icao]['t1']) < 10): # use multi message decoding - try: - latlon = adsb.position( - self.acs[icao][0], - self.acs[icao][1], - self.acs[icao]['t0'], - self.acs[icao]['t1'], - self.lat0, self.lon0 - ) - except: - # mix of surface and airborne position message - continue + # try: + latlon = pms.adsb.position( + self.acs[icao][0], + self.acs[icao][1], + self.acs[icao]['t0'], + self.acs[icao]['t1'], + self.lat0, self.lon0 + ) + # except: + # # mix of surface and airborne position message + # continue else: latlon = None @@ -105,70 +106,71 @@ class Stream(): self.acs[icao]['tpos'] = t self.acs[icao]['lat'] = latlon[0] self.acs[icao]['lon'] = latlon[1] - self.acs[icao]['alt'] = adsb.altitude(msg) + self.acs[icao]['alt'] = pms.adsb.altitude(msg) local_updated_acs_buffer.append(icao) # Uncertainty & accuracy if (5 <= tc <= 8): - if self.acs[icao]['adsb_version'] == 1: + if self.acs[icao]['ver'] == 1: if self.acs[icao]['nic_s'] != None: - self.nic = adsb.nic_v1(msg, self.acs[icao]['nic_s']) - elif self.acs[icao]['adsb_version'] == 2: + self.acs[icao]['NIC'] = pms.adsb.nic_v1(msg, self.acs[icao]['nic_s']) + elif self.acs[icao]['ver'] == 2: if self.acs[icao]['nic_a'] != None and self.acs[icao]['nic_b'] != None: - self.nic = adsb.nic_v2(msg, self.nic_a, self.acs[icao]['nic_b'], self.acs[icao]['nic_c']) + self.acs[icao]['NIC'] = pms.adsb.nic_v2(msg, self.acs[icao]['nic_a'], self.acs[icao]['nic_b'], self.acs[icao]['nic_c']) if (9 <= tc <= 18): - if self.acs[icao]['adsb_version'] == 1: + if self.acs[icao]['ver'] == 1: if self.acs[icao]['nic_s'] != None: - self.nic = adsb.nic_v1(msg, self.acs[icao]['nic_s']) - elif self.acs[icao]['adsb_version'] == 2: - self.acs[icao]['nic_b'] = adsb.nic_b(msg) + self.acs[icao]['NIC'] = pms.adsb.nic_v1(msg, self.acs[icao]['nic_s']) + elif self.acs[icao]['ver'] == 2: + self.acs[icao]['nic_b'] = pms.adsb.nic_b(msg) if self.acs[icao]['nic_a'] != None and self.acs[icao]['nic_b'] != None: - self.nic = adsb.nic_v2(msg, self.acs[icao]['nic_a'], self.nic_b, self.acs[icao]['nic_c']) + self.acs[icao]['NIC'] = pms.adsb.nic_v2(msg, self.acs[icao]['nic_a'], self.acs[icao]['nic_b'], self.acs[icao]['nic_c']) if tc == 19: - self.acs[icao]['nac_v'] = adsb.nac_v(msg) + if self.acs[icao]['ver'] in [1, 2]: + self.acs[icao]['NACv'] = pms.adsb.nac_v(msg) if (20 <= tc <= 22): - if self.acs[icao]['adsb_version'] == 1: + if self.acs[icao]['ver'] == 1: if self.acs[icao]['nic_s'] != None: - self.nic = adsb.nic_v1(msg, self.acs[icao]['nic_s']) - elif self.acs[icao]['adsb_version'] == 2: + self.acs[icao]['NIC'] = pms.adsb.nic_v1(msg, self.acs[icao]['nic_s']) + elif self.acs[icao]['ver'] == 2: if self.acs[icao]['nic_a'] != None and self.acs[icao]['nic_b'] != None: - self.nic = adsb.nic_v2(msg, self.acs[icao]['nic_a'], self.acs[icao]['nic_b'], self.acs[icao]['nic_c']) + self.acs[icao]['NIC'] = pms.adsb.nic_v2(msg, self.acs[icao]['nic_a'], self.acs[icao]['nic_b'], self.acs[icao]['nic_c']) if tc == 29: - if self.acs[icao]['adsb_version'] != None: - self.acs[icao]['sil'] = adsb.sil(msg, self.acs[icao]['adsb_version']) - self.acs[icao]['nac_p'] = adsb.nac_p(msg) + if self.acs[icao]['ver'] != None: + self.acs[icao]['SIL'], self.acs[icao]['sil_s'] = pms.adsb.sil(msg, self.acs[icao]['ver']) + self.acs[icao]['NACp'] = pms.adsb.nac_p(msg) if tc == 31: - self.acs[icao]['adsb_version'] = adsb.version(msg) - self.acs[icao]['sil'] = adsb.version(msg) - self.acs[icao]['nac_p'] = adsb.nac_p(msg) - if self.acs[icao]['adsb_version'] == 1: - self.acs[icao]['nic_s'] = adsb.nic_s(msg) - elif self.acs[icao]['adsb_version'] == 2: - self.acs[icao]['nic_a'], self.acs[icao]['nic_c'] = adsb.nic_a_c(msg) + self.acs[icao]['ver'] = pms.adsb.version(msg) + self.acs[icao]['SIL'] = pms.adsb.version(msg) + self.acs[icao]['NACp'] = pms.adsb.nac_p(msg) + if self.acs[icao]['ver'] == 1: + self.acs[icao]['nic_s'] = pms.adsb.nic_s(msg) + elif self.acs[icao]['ver'] == 2: + self.acs[icao]['nic_a'], self.acs[icao]['nic_c'] = pms.adsb.nic_a_c(msg) - # process ehs message - for t, msg in zip(ehs_ts, ehs_msgs): - icao = ehs.icao(msg) + # process commb message + for t, msg in zip(commb_ts, commb_msgs): + icao = pms.icao(msg) if icao not in self.acs: continue - bds = ehs.BDS(msg) + bds = pms.bds.infer(msg) if bds == 'BDS50': - tas = ehs.tas50(msg) + tas = pms.commb.tas50(msg) if tas: self.acs[icao]['t50'] = t self.acs[icao]['tas'] = tas elif bds == 'BDS60': - ias = ehs.ias60(msg) - hdg = ehs.hdg60(msg) - mach = ehs.mach60(msg) + ias = pms.commb.ias60(msg) + hdg = pms.commb.hdg60(msg) + mach = pms.commb.mach60(msg) if ias or hdg or mach: self.acs[icao]['t60'] = t @@ -181,7 +183,7 @@ class Stream(): # clear up old data for icao in list(self.acs.keys()): - if self.t - self.acs[icao]['t'] > self.cache_timeout: + if self.t - self.acs[icao]['updated'] > self.cache_timeout: del self.acs[icao] continue