Advertisement
DeaD_EyE

adsb_whatever1.py

Apr 3rd, 2016
188
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.81 KB | None | 0 0
  1. from __future__ import print_function
  2. import time
  3. from collections import namedtuple
  4. from datetime import datetime
  5. from threading import Thread
  6. import pyModeS as pym
  7. from pprint import pprint
  8.  
  9. def callback(data):
  10.     pprint(data)
  11.     print()
  12.  
  13.  
  14. class Sender:
  15.     def __init__(self, p, v, i, callback):
  16.         self.p = p
  17.         self.v = v
  18.         self.i = i
  19.         self.callback = callback
  20.        
  21.     def get(self):
  22.         ret = {}
  23.         for icao, lat, lon, raw_even, raw_odd in self.p.positions:
  24.             ret[icao] = {'lat': lat,
  25.                          'lon': lon,
  26.                          'raw_even': raw_even,
  27.                          'raw_odd': raw_odd}
  28.         for icao, v, raw in self.v.velocity:
  29.             data = {'velocity': v, 'velocity_raw': raw}
  30.             try:
  31.                 ret[icao].update(data)
  32.             except:
  33.                 continue
  34.         for icao, callsign, callsign_raw in self.i.identifications:
  35.             data = {'callsign': callsign, 'callsign_raw': callsign_raw}
  36.             try:
  37.                 ret[icao].update(data)
  38.             except:
  39.                 continue
  40.         return ret
  41.    
  42.     def run(self):
  43.         while True:
  44.             time.sleep(1)
  45.             self.callback(self.get())
  46.  
  47. class Data:
  48.    
  49.     EVEN = 0
  50.     ODD = 1
  51.     MAX_AGE = 60
  52.    
  53.     def __init__(self):
  54.         self._data = {}
  55.    
  56.     def __bool__(self):
  57.         if len(self._data):
  58.             return True
  59.         else:
  60.             return False
  61.    
  62.     def __len__(self):
  63.         return len(self._data)
  64.    
  65.     def update(self, msg):
  66.         frame = self.create_entry(msg)
  67.         self._data.update(frame)
  68.         self.wipe()
  69.  
  70.     def create_entry(self, msg):
  71.         return {datetime.now(): msg}
  72.    
  73.     def is_old(self, dt):
  74.         if self.tdelta(dt) > self.MAX_AGE:
  75.             return True
  76.         else:
  77.             return False
  78.    
  79.     def tdelta(self, dt):
  80.         return (datetime.now() - dt).seconds
  81.    
  82.     def wipe(self):
  83.         to_delete = []
  84.         for key in self._data.keys():
  85.             if self.is_old(key):
  86.                 to_delete.append(key)
  87.         for i in to_delete:
  88.             del self._data[i]
  89.  
  90.  
  91. class AirbonePositions(Data):
  92.    
  93.     def __len__(self):
  94.         return len(self.positions)
  95.    
  96.     def get_sorted_items(self):
  97.         sorted_items = sorted(self._data.items(),
  98.             key=lambda i: (datetime.now() - i[0]).microseconds)
  99.         return sorted_items
  100.  
  101.    
  102.     def get_position_dict(self):
  103.         pos_dict = {}
  104.         for key, value in self.get_sorted_items():
  105.             icao = pym.adsb.icao(value)
  106.             oeflag = pym.adsb.oe_flag(value)
  107.             data = {oeflag: (key, value)}
  108.             if icao not in pos_dict:
  109.                 pos_dict[icao] = data
  110.             elif oeflag not in pos_dict[icao]:
  111.                 pos_dict[icao].update(data)
  112.             elif oeflag in pos_dict[icao]:
  113.                 t = pos_dict[icao][oeflag][0]
  114.                 td = (t - data[oeflag][0]).microseconds
  115.                 if td < 0:
  116.                     pos_dict[icao].update(data)
  117.         return pos_dict
  118.    
  119.     @property
  120.     def positions(self):
  121.         ret = []
  122.         positions = self.get_position_dict()
  123.         for icao, item in positions.items():
  124.             if self.EVEN in item and self.ODD in item:
  125.                 lat, lon = pym.adsb.position(
  126.                         item[0][1],
  127.                         item[1][1],
  128.                         item[0][0],
  129.                         item[1][0],
  130.                         )
  131.                 ret.append((icao, lat, lon, item[0][1], item[1][1]))
  132.         return ret
  133.  
  134.  
  135. class Identifications(Data):
  136.    
  137.     def __len__(self):
  138.         return len(self.identifications)
  139.    
  140.     @property
  141.     def identifications(self):
  142.         return {(pym.adsb.icao(d), pym.adsb.callsign(d).replace('_','').replace('*', ''), d) for
  143.                 d in identifications._data.values()}
  144.     def callsign(self, icao):
  145.         for data in self._data.values():
  146.             if icao == pym.adsb.icao(data):
  147.                 return pym.adsb.callsign(data).replace('_','').replace('*', '')
  148.  
  149.  
  150. class Velocity(Data):
  151.    
  152.     def __len(self):
  153.         return len(velocity)
  154.    
  155.     @property
  156.     def velocity(self):
  157.         return {(pym.adsb.icao(d), pym.adsb.velocity(d), d)
  158.                 for d in self._data.values()}
  159.    
  160.     def v(self, icao):
  161.         for data in self._data.values():
  162.             if icao == pym.adsb.icao(data):
  163.                 return pym.adsb.velocity(data)
  164.            
  165.            
  166. def stripper(data):
  167.     return data.lstrip('*').rstrip(';\n\r')
  168.  
  169. def get_df_tc(data):
  170.     #print(pym.adsb.df(data), pym.adsb.typecode(data))
  171.     return (pym.adsb.df(data), pym.adsb.typecode(data))
  172.  
  173. def selector(data):
  174.     for mode in msgtypes:
  175.         df, tc = get_df_tc(data)
  176.         if mode['df'] == df and mode['tc_min'] <= tc <= mode['tc_max']:
  177.             return mode['msgtype']
  178.  
  179. def aircraft_identification(data):
  180.     identifications.update(data)
  181.    
  182. def airbone_positions(data):
  183.     positions.update(data)
  184.    
  185. def airbone_velocity(data):
  186.     velocity.update(data)
  187.  
  188. msgtypes = [{'df': 17, 'tc_min': 1, 'tc_max': 4,
  189.              'msgtype': aircraft_identification},
  190.             {'df': 17, 'tc_min': 9, 'tc_max': 18,
  191.              'msgtype': airbone_positions},
  192.             {'df': 17, 'tc_min': 19, 'tc_max': 19,
  193.              'msgtype': airbone_velocity},
  194.             ]
  195.  
  196. positions = AirbonePositions()
  197. identifications = Identifications()
  198. velocity = Velocity()
  199. sender = Sender(positions, velocity, identifications, callback)
  200. sender_thread = Thread(target=sender.run)
  201. sender_thread.start()
  202.  
  203. with open('adsb.record') as fd:
  204.     for line in fd:
  205.         msg = stripper(line)
  206.         func = selector(msg)
  207.         if func:
  208.             func(msg)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement