Merge status + position messages from same address

pull/68/head
Konstantin Gründger 2018-04-27 21:48:14 +02:00
rodzic 511e4cb496
commit ed6ef5fb8d
2 zmienionych plików z 58 dodań i 23 usunięć

Wyświetl plik

@ -1,6 +1,7 @@
import logging import logging
from mgrs import MGRS from mgrs import MGRS
from haversine import haversine
from ogn.commands.dbutils import session from ogn.commands.dbutils import session
from ogn.model import AircraftBeacon, ReceiverBeacon, Location from ogn.model import AircraftBeacon, ReceiverBeacon, Location
@ -12,14 +13,12 @@ logger = logging.getLogger(__name__)
myMGRS = MGRS() myMGRS = MGRS()
def replace_lonlat_with_wkt(message, reference_position=None): def replace_lonlat_with_wkt(message, reference_receiver=None):
from haversine import haversine
latitude = message['latitude'] latitude = message['latitude']
longitude = message['longitude'] longitude = message['longitude']
if reference_position is not None: if reference_receiver is not None:
message['distance'] = 1000.0 * haversine((reference_position['latitude'], reference_position['longitude']), (latitude, longitude)) message['distance'] = 1000.0 * haversine((reference_receiver['latitude'], reference_receiver['longitude']), (latitude, longitude))
location = Location(longitude, latitude) location = Location(longitude, latitude)
message['location_wkt'] = location.to_wkt() message['location_wkt'] = location.to_wkt()
@ -28,40 +27,66 @@ def replace_lonlat_with_wkt(message, reference_position=None):
del message['longitude'] del message['longitude']
return message 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 beacon = None
global previous_message
global receivers
if raw_message[0] != '#': if raw_message[0] != '#':
try: try:
message = parse(raw_message, reference_date) 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: except NotImplementedError as e:
logger.error('Received message: {}'.format(raw_message)) logger.error('Received message: {}'.format(raw_message))
logger.error(e) logger.error(e)
return None
except ParseError as e: except ParseError as e:
logger.error('Received message: {}'.format(raw_message)) logger.error('Received message: {}'.format(raw_message))
logger.error('Drop packet, {}'.format(e.message)) logger.error('Drop packet, {}'.format(e.message))
return None
except TypeError as e: except TypeError as e:
logger.error('TypeError: {}'.format(raw_message)) logger.error('TypeError: {}'.format(raw_message))
return None
except Exception as e: except Exception as e:
logger.error(raw_message) logger.error(raw_message)
logger.error(e) 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 return beacon

Wyświetl plik

@ -2,7 +2,7 @@ import datetime
import unittest import unittest
import unittest.mock as mock 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): class ProcessManagerTest(unittest.TestCase):
@ -23,6 +23,16 @@ class ProcessManagerTest(unittest.TestCase):
process_beacon(string2) process_beacon(string2)
self.assertEqual(mock_session.bulk_save_objects.call_count, 1) 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__': if __name__ == '__main__':
unittest.main() unittest.main()