diff --git a/ogn/gateway/process.py b/ogn/gateway/process.py index 0bd75bc..9f3e86f 100644 --- a/ogn/gateway/process.py +++ b/ogn/gateway/process.py @@ -1,6 +1,7 @@ import logging from mgrs import MGRS +from haversine import haversine from ogn.commands.dbutils import session from ogn.model import AircraftBeacon, ReceiverBeacon, Location @@ -12,14 +13,12 @@ logger = logging.getLogger(__name__) myMGRS = MGRS() -def replace_lonlat_with_wkt(message, reference_position=None): - from haversine import haversine - +def replace_lonlat_with_wkt(message, reference_receiver=None): latitude = message['latitude'] longitude = message['longitude'] - if reference_position is not None: - message['distance'] = 1000.0 * haversine((reference_position['latitude'], reference_position['longitude']), (latitude, longitude)) + if reference_receiver is not None: + message['distance'] = 1000.0 * haversine((reference_receiver['latitude'], reference_receiver['longitude']), (latitude, longitude)) location = Location(longitude, latitude) message['location_wkt'] = location.to_wkt() @@ -28,40 +27,66 @@ def replace_lonlat_with_wkt(message, reference_position=None): del message['longitude'] return message +previous_message = None +receivers = dict() -def message_to_beacon(raw_message, reference_date, receivers=None): + +def message_to_beacon(raw_message, reference_date, wait_for_brother=False): beacon = None + global previous_message + global receivers if raw_message[0] != '#': try: message = parse(raw_message, reference_date) - if message['aprs_type'] == 'position': - if message['beacon_type'] == 'receiver_beacon': - receivers.update({message['name']: {'latitude': message['latitude'], 'longitude': message['longitude']}}) - message = replace_lonlat_with_wkt(message) - elif message['beacon_type'] == 'aircraft_beacon': - reference_receiver = receivers.get(message['receiver_name']) - message = replace_lonlat_with_wkt(message, reference_position=reference_receiver) - - if message['beacon_type'] == 'aircraft_beacon' and message['aprs_type'] == 'position': - beacon = AircraftBeacon(**message) - elif message['beacon_type'] == 'aircraft_beacon' and message['aprs_type'] == 'status': - pass - elif message['beacon_type'] == 'receiver_beacon': - beacon = ReceiverBeacon(**message) - else: - print("Whoops: what is this: {}".format(message)) except NotImplementedError as e: logger.error('Received message: {}'.format(raw_message)) logger.error(e) + return None except ParseError as e: logger.error('Received message: {}'.format(raw_message)) logger.error('Drop packet, {}'.format(e.message)) + return None except TypeError as e: logger.error('TypeError: {}'.format(raw_message)) + return None except Exception as e: logger.error(raw_message) logger.error(e) + return None + + # update reference receivers and distance to the receiver + if message['aprs_type'] == 'position': + if message['beacon_type'] in ['receiver_beacon', 'aprs_receiver', 'receiver']: + receivers.update({message['name']: {'latitude': message['latitude'], 'longitude': message['longitude']}}) + message = replace_lonlat_with_wkt(message) + elif message['beacon_type'] in ['aircraft_beacon', 'aprs_aircraft', 'flarm', 'tracker']: + reference_receiver = receivers.get(message['receiver_name']) + message = replace_lonlat_with_wkt(message, reference_receiver=reference_receiver) + + # optional: merge different beacon types + params = dict() + if wait_for_brother is True: + if previous_message is None: + previous_message = message + return None + elif message['name'] == previous_message['name'] and message['timestamp'] == previous_message['timestamp']: + params = message + params.update(previous_message) + params['aprs_type'] = 'merged' + else: + params = previous_message + previous_message = message + else: + params = message + + # create beacons + if params['beacon_type'] in ['aircraft_beacon', 'aprs_aircraft', 'flarm', 'tracker']: + beacon = AircraftBeacon(**params) + elif message['beacon_type'] in ['receiver_beacon', 'aprs_receiver', 'receiver']: + beacon = ReceiverBeacon(**params) + else: + print("Whoops: what is this: {}".format(params)) return beacon diff --git a/tests/gateway/test_process.py b/tests/gateway/test_process.py index 5fe6ca1..74847b7 100644 --- a/tests/gateway/test_process.py +++ b/tests/gateway/test_process.py @@ -2,7 +2,7 @@ import datetime import unittest import unittest.mock as mock -from ogn.gateway.process import process_beacon +from ogn.gateway.process import process_beacon, message_to_beacon class ProcessManagerTest(unittest.TestCase): @@ -23,6 +23,16 @@ class ProcessManagerTest(unittest.TestCase): process_beacon(string2) self.assertEqual(mock_session.bulk_save_objects.call_count, 1) + def test_message_to_beacon_brother(self): + string1 = "Saleve>OGNSDR,TCPIP*,qAC,GLIDERN1:/132624h4607.70NI00610.41E&/A=004198 Antenna: chinese, on a pylon, 20 meter above ground" + string2 = "Saleve>OGNSDR,TCPIP*,qAC,GLIDERN1:>132624h v0.2.7.arm CPU:1.7 RAM:812.3/1022.5MB NTP:1.8ms/+4.5ppm 0.000V 0.000A 3/4Acfts[1h] RF:+67+2.9ppm/+4.18dB/+11.7dB@10km[5018]/+17.2dB@10km[8/16]" + + beacon = message_to_beacon(string1, reference_date=datetime.date(2015, 1, 1), wait_for_brother=True) + self.assertIsNone(beacon) + + beacon = message_to_beacon(string2, reference_date=datetime.date(2015, 1, 1), wait_for_brother=True) + self.assertIsNotNone(beacon) + self.assertEqual(beacon.aprs_type, 'merged') if __name__ == '__main__': unittest.main()