Merge pull request #31 from Meisterschueler/feature/+naviter_beacons

Feature/+naviter beacons
pull/32/head
Meisterschueler 2017-09-30 09:46:09 +02:00 zatwierdzone przez GitHub
commit dd40892ca4
26 zmienionych plików z 358 dodań i 102 usunięć

Wyświetl plik

@ -2,6 +2,7 @@
## Unreleased ## Unreleased
- parser: Added support for heared aircrafts - parser: Added support for heared aircrafts
- parser: Added support for naviter beacons
- client: Allow client to do sequential connect-disconnect - client: Allow client to do sequential connect-disconnect
## 0.7.1 - 2017-06-05 ## 0.7.1 - 2017-06-05

0
ogn/__init__.py 100644
Wyświetl plik

Wyświetl plik

@ -1,2 +1,2 @@
from ogn.parser.parse import parse_aprs, parse_ogn_beacon, parse_ogn_receiver_beacon, parse_ogn_aircraft_beacon # flake8: noqa from ogn.parser.parse import parse_aprs, parse_ogn_beacon, parse_receiver_beacon, parse_aircraft_beacon # flake8: noqa
from ogn.parser.exceptions import ParseError, AprsParseError, OgnParseError, AmbigousTimeError # flake8: noqa from ogn.parser.exceptions import ParseError, AprsParseError, OgnParseError, AmbigousTimeError # flake8: noqa

Wyświetl plik

@ -1,10 +1,17 @@
import re import re
from datetime import datetime from datetime import datetime
from ogn.parser.utils import createTimestamp, parseAngle, kts2kmh, feet2m, fpm2ms from ogn.parser.utils import createTimestamp, parseAngle, kts2kmh, feet2m
from ogn.parser.pattern import PATTERN_APRS_POSITION, PATTERN_APRS_STATUS, PATTERN_RECEIVER_BEACON, PATTERN_AIRCRAFT_BEACON from ogn.parser.pattern import PATTERN_APRS_POSITION, PATTERN_APRS_STATUS
from ogn.parser.exceptions import AprsParseError, OgnParseError from ogn.parser.exceptions import AprsParseError, OgnParseError
from ogn.parser.parse_ogn import parse_aircraft_beacon, parse_receiver_beacon
from ogn.parser.parse_naviter import parse as parse_naviter_beacon
from ogn.parser.parse_lt24 import parse as parse_lt24_beacon
from ogn.parser.parse_spider import parse as parse_spider_beacon
from ogn.parser.parse_spot import parse as parse_spot_beacon
from ogn.parser.parse_skylines import parse as parse_skylines_beacon
def parse_aprs(message, reference_date=None, reference_time=None): def parse_aprs(message, reference_date=None, reference_time=None):
if reference_date is None: if reference_date is None:
@ -15,8 +22,9 @@ def parse_aprs(message, reference_date=None, reference_time=None):
match_position = re.search(PATTERN_APRS_POSITION, message) match_position = re.search(PATTERN_APRS_POSITION, message)
if match_position: if match_position:
return {'name': match_position.group('callsign'), return {'name': match_position.group('callsign'),
'receiver_name': match_position.group('receiver'),
'dstcall': match_position.group('dstcall'), 'dstcall': match_position.group('dstcall'),
'relay': match_position.group('relay') if match_position.group('relay') else None,
'receiver_name': match_position.group('receiver'),
'timestamp': createTimestamp(match_position.group('time'), reference_date, reference_time), 'timestamp': createTimestamp(match_position.group('time'), reference_date, reference_time),
'latitude': parseAngle('0' + match_position.group('latitude') + (match_position.group('latitude_enhancement') or '0')) * 'latitude': parseAngle('0' + match_position.group('latitude') + (match_position.group('latitude_enhancement') or '0')) *
(-1 if match_position.group('latitude_sign') == 'S' else 1), (-1 if match_position.group('latitude_sign') == 'S' else 1),
@ -27,81 +35,68 @@ def parse_aprs(message, reference_date=None, reference_time=None):
'track': int(match_position.group('course')) if match_position.group('course_extension') else None, 'track': int(match_position.group('course')) if match_position.group('course_extension') else None,
'ground_speed': int(match_position.group('ground_speed')) * kts2kmh if match_position.group('ground_speed') else None, 'ground_speed': int(match_position.group('ground_speed')) * kts2kmh if match_position.group('ground_speed') else None,
'altitude': int(match_position.group('altitude')) * feet2m, 'altitude': int(match_position.group('altitude')) * feet2m,
'comment': match_position.group('comment')} 'comment': match_position.group('comment'),
'aprs_type': 'position'}
match_status = re.search(PATTERN_APRS_STATUS, message) match_status = re.search(PATTERN_APRS_STATUS, message)
if match_status: if match_status:
return {'name': match_status.group('callsign'), return {'name': match_status.group('callsign'),
'receiver_name': match_status.group('receiver'),
'dstcall': match_status.group('dstcall'), 'dstcall': match_status.group('dstcall'),
'receiver_name': match_status.group('receiver'),
'timestamp': createTimestamp(match_status.group('time'), reference_date, reference_time), 'timestamp': createTimestamp(match_status.group('time'), reference_date, reference_time),
'comment': match_status.group('comment')} 'comment': match_status.group('comment'),
'aprs_type': 'status'}
raise AprsParseError(message) raise AprsParseError(message)
def parse_ogn_aircraft_beacon(aprs_comment): def parse_ogn_beacon(aprs_comment, dstcall="APRS"):
ac_match = re.search(PATTERN_AIRCRAFT_BEACON, aprs_comment) if dstcall == "APRS": # this can be a receiver or an aircraft
if ac_match:
return {'address_type': int(ac_match.group('details'), 16) & 0b00000011,
'aircraft_type': (int(ac_match.group('details'), 16) & 0b01111100) >> 2,
'stealth': (int(ac_match.group('details'), 16) & 0b10000000) >> 7 == 1,
'address': ac_match.group('id'),
'climb_rate': int(ac_match.group('climb_rate')) * fpm2ms if ac_match.group('climb_rate') else None,
'turn_rate': float(ac_match.group('turn_rate')) if ac_match.group('turn_rate') else None,
'flightlevel': float(ac_match.group('flight_level')) if ac_match.group('flight_level') else None,
'signal_quality': float(ac_match.group('signal_quality')) if ac_match.group('signal_quality') else None,
'error_count': int(ac_match.group('errors')) if ac_match.group('errors') else None,
'frequency_offset': float(ac_match.group('frequency_offset')) if ac_match.group('frequency_offset') else None,
'gps_status': ac_match.group('gps_accuracy') if ac_match.group('gps_accuracy') else None,
'software_version': float(ac_match.group('flarm_software_version')) if ac_match.group('flarm_software_version') else None,
'hardware_version': int(ac_match.group('flarm_hardware_version'), 16) if ac_match.group('flarm_hardware_version') else None,
'real_address': ac_match.group('flarm_id') if ac_match.group('flarm_id') else None,
'signal_power': float(ac_match.group('signal_power')) if ac_match.group('signal_power') else None,
'proximity': [hear[4:] for hear in ac_match.group('proximity').split(" ")] if ac_match.group('proximity') else None}
else:
return None
def parse_ogn_receiver_beacon(aprs_comment):
rec_match = re.search(PATTERN_RECEIVER_BEACON, aprs_comment)
if rec_match:
return {'version': rec_match.group('version'),
'platform': rec_match.group('platform'),
'cpu_load': float(rec_match.group('cpu_load')),
'free_ram': float(rec_match.group('ram_free')),
'total_ram': float(rec_match.group('ram_total')),
'ntp_error': float(rec_match.group('ntp_offset')),
'rt_crystal_correction': float(rec_match.group('ntp_correction')),
'voltage': float(rec_match.group('voltage')) if rec_match.group('voltage') else None,
'amperage': float(rec_match.group('amperage')) if rec_match.group('amperage') else None,
'cpu_temp': float(rec_match.group('cpu_temperature')) if rec_match.group('cpu_temperature') else None,
'senders_visible': int(rec_match.group('visible_senders')) if rec_match.group('visible_senders') else None,
'senders_total': int(rec_match.group('senders')) if rec_match.group('senders') else None,
'rec_crystal_correction': int(rec_match.group('rf_correction_manual')) if rec_match.group('rf_correction_manual') else None,
'rec_crystal_correction_fine': float(rec_match.group('rf_correction_automatic')) if rec_match.group('rf_correction_automatic') else None,
'rec_input_noise': float(rec_match.group('signal_quality')) if rec_match.group('signal_quality') else None,
'senders_signal': float(rec_match.group('senders_signal_quality')) if rec_match.group('senders_signal_quality') else None,
'senders_messages': float(rec_match.group('senders_messages')) if rec_match.group('senders_messages') else None,
'good_senders_signal': float(rec_match.group('good_senders_signal_quality')) if rec_match.group('good_senders_signal_quality') else None,
'good_senders': float(rec_match.group('good_senders')) if rec_match.group('good_senders') else None,
'good_and_bad_senders': float(rec_match.group('good_and_bad_senders')) if rec_match.group('good_and_bad_senders') else None}
else:
return None
def parse_ogn_beacon(aprs_comment):
if not aprs_comment: if not aprs_comment:
return {'beacon_type': 'receiver_beacon'} return {'beacon_type': 'receiver_beacon'}
ac_data = parse_ogn_aircraft_beacon(aprs_comment) ac_data = parse_aircraft_beacon(aprs_comment)
if ac_data: if ac_data:
ac_data.update({'beacon_type': 'aircraft_beacon'}) ac_data.update({'beacon_type': 'aircraft_beacon'})
return ac_data return ac_data
rc_data = parse_ogn_receiver_beacon(aprs_comment) rc_data = parse_receiver_beacon(aprs_comment)
if rc_data: if rc_data:
rc_data.update({'beacon_type': 'receiver_beacon'}) rc_data.update({'beacon_type': 'receiver_beacon'})
return rc_data return rc_data
raise OgnParseError(aprs_comment) raise OgnParseError(aprs_comment)
elif dstcall == "OGFLR":
ac_data = parse_aircraft_beacon(aprs_comment)
ac_data.update({'beacon_type': 'aircraft_beacon'})
return ac_data
elif dstcall == "OGNTRK":
ac_data = parse_aircraft_beacon(aprs_comment)
ac_data.update({'beacon_type': 'aircraft_beacon'})
return ac_data
elif dstcall == "OGNSDR":
ac_data = parse_receiver_beacon(aprs_comment)
ac_data.update({'beacon_type': 'receiver_beacon'})
return ac_data
elif dstcall == "OGLT24":
ac_data = parse_lt24_beacon(aprs_comment)
ac_data.update({'beacon_type': 'lt24_beacon'})
return ac_data
elif dstcall == "OGNAVI":
ac_data = parse_naviter_beacon(aprs_comment)
ac_data.update({'beacon_type': 'naviter_beacon'})
return ac_data
elif dstcall == "OGSKYL":
ac_data = parse_skylines_beacon(aprs_comment)
ac_data.update({'beacon_type': 'skylines_beacon'})
return ac_data
elif dstcall == "OGSPID":
ac_data = parse_spider_beacon(aprs_comment)
ac_data.update({'beacon_type': 'spider_beacon'})
return ac_data
elif dstcall == "OGSPOT":
ac_data = parse_spot_beacon(aprs_comment)
ac_data.update({'beacon_type': 'spot_beacon'})
return ac_data
else:
raise ValueError("dstcall {} unknown".format(dstcall))

Wyświetl plik

@ -0,0 +1,2 @@
def parse(aprs_comment):
raise NotImplementedError("LT24 beacon parser not yet implemented")

Wyświetl plik

@ -0,0 +1,16 @@
import re
from ogn.parser.utils import fpm2ms
from ogn.parser.pattern import PATTERN_NAVITER_BEACON
def parse(aprs_comment):
match = re.search(PATTERN_NAVITER_BEACON, aprs_comment)
return {'stealth': (int(match.group('details'), 16) & 0b1000000000000000) >> 15 == 1,
'do_not_track': (int(match.group('details'), 16) & 0b0100000000000000) >> 14 == 1,
'aircraft_type': (int(match.group('details'), 16) & 0b0011110000000000) >> 10,
'address_type': (int(match.group('details'), 16) & 0b0000001111110000) >> 4,
'reserved': (int(match.group('details'), 16) & 0b0000000000001111),
'address': match.group('id'),
'climb_rate': int(match.group('climb_rate')) * fpm2ms if match.group('climb_rate') else None,
'turn_rate': float(match.group('turn_rate')) if match.group('turn_rate') else None}

Wyświetl plik

@ -0,0 +1,54 @@
import re
from ogn.parser.utils import fpm2ms
from ogn.parser.pattern import PATTERN_RECEIVER_BEACON, PATTERN_AIRCRAFT_BEACON
def parse_aircraft_beacon(aprs_comment):
ac_match = re.search(PATTERN_AIRCRAFT_BEACON, aprs_comment)
if ac_match:
return {'address_type': int(ac_match.group('details'), 16) & 0b00000011,
'aircraft_type': (int(ac_match.group('details'), 16) & 0b01111100) >> 2,
'stealth': (int(ac_match.group('details'), 16) & 0b10000000) >> 7 == 1,
'address': ac_match.group('id'),
'climb_rate': int(ac_match.group('climb_rate')) * fpm2ms if ac_match.group('climb_rate') else None,
'turn_rate': float(ac_match.group('turn_rate')) if ac_match.group('turn_rate') else None,
'flightlevel': float(ac_match.group('flight_level')) if ac_match.group('flight_level') else None,
'signal_quality': float(ac_match.group('signal_quality')) if ac_match.group('signal_quality') else None,
'error_count': int(ac_match.group('errors')) if ac_match.group('errors') else None,
'frequency_offset': float(ac_match.group('frequency_offset')) if ac_match.group('frequency_offset') else None,
'gps_status': ac_match.group('gps_accuracy') if ac_match.group('gps_accuracy') else None,
'software_version': float(ac_match.group('flarm_software_version')) if ac_match.group('flarm_software_version') else None,
'hardware_version': int(ac_match.group('flarm_hardware_version'), 16) if ac_match.group('flarm_hardware_version') else None,
'real_address': ac_match.group('flarm_id') if ac_match.group('flarm_id') else None,
'signal_power': float(ac_match.group('signal_power')) if ac_match.group('signal_power') else None,
'proximity': [hear[4:] for hear in ac_match.group('proximity').split(" ")] if ac_match.group('proximity') else None}
else:
return None
def parse_receiver_beacon(aprs_comment):
rec_match = re.search(PATTERN_RECEIVER_BEACON, aprs_comment)
if rec_match:
return {'version': rec_match.group('version'),
'platform': rec_match.group('platform'),
'cpu_load': float(rec_match.group('cpu_load')),
'free_ram': float(rec_match.group('ram_free')),
'total_ram': float(rec_match.group('ram_total')),
'ntp_error': float(rec_match.group('ntp_offset')),
'rt_crystal_correction': float(rec_match.group('ntp_correction')),
'voltage': float(rec_match.group('voltage')) if rec_match.group('voltage') else None,
'amperage': float(rec_match.group('amperage')) if rec_match.group('amperage') else None,
'cpu_temp': float(rec_match.group('cpu_temperature')) if rec_match.group('cpu_temperature') else None,
'senders_visible': int(rec_match.group('visible_senders')) if rec_match.group('visible_senders') else None,
'senders_total': int(rec_match.group('senders')) if rec_match.group('senders') else None,
'rec_crystal_correction': int(rec_match.group('rf_correction_manual')) if rec_match.group('rf_correction_manual') else None,
'rec_crystal_correction_fine': float(rec_match.group('rf_correction_automatic')) if rec_match.group('rf_correction_automatic') else None,
'rec_input_noise': float(rec_match.group('signal_quality')) if rec_match.group('signal_quality') else None,
'senders_signal': float(rec_match.group('senders_signal_quality')) if rec_match.group('senders_signal_quality') else None,
'senders_messages': float(rec_match.group('senders_messages')) if rec_match.group('senders_messages') else None,
'good_senders_signal': float(rec_match.group('good_senders_signal_quality')) if rec_match.group('good_senders_signal_quality') else None,
'good_senders': float(rec_match.group('good_senders')) if rec_match.group('good_senders') else None,
'good_and_bad_senders': float(rec_match.group('good_and_bad_senders')) if rec_match.group('good_and_bad_senders') else None}
else:
return None

Wyświetl plik

@ -0,0 +1,2 @@
def parse(aprs_comment):
raise NotImplementedError("Skylines beacon parser not yet implemented")

Wyświetl plik

@ -0,0 +1,2 @@
def parse(aprs_comment):
raise NotImplementedError("Spider beacon parser not yet implemented")

Wyświetl plik

@ -0,0 +1,2 @@
def parse(aprs_comment):
raise NotImplementedError("SPOT beacon parser not yet implemented")

Wyświetl plik

@ -1,8 +1,14 @@
import re import re
PATTERN_APRS_POSITION = re.compile(r"^(?P<callsign>.+?)>(?P<dstcall>[A-Z0-9]+),.+,(?P<receiver>.+?):/(?P<time>\d{6})+h(?P<latitude>\d{4}\.\d{2})(?P<latitude_sign>N|S)(?P<symbol_table>.)(?P<longitude>\d{5}\.\d{2})(?P<longitude_sign>E|W)(?P<symbol>.)(?P<course_extension>(?P<course>\d{3})/(?P<ground_speed>\d{3}))?/A=(?P<altitude>\d{6})(?P<pos_extension>\s!W((?P<latitude_enhancement>\d)(?P<longitude_enhancement>\d))!)?(?:\s(?P<comment>.*))?$") PATTERN_APRS_POSITION = re.compile(r"^(?P<callsign>.+?)>(?P<dstcall>[A-Z0-9]+),((?P<relay>[A-Za-z0-9]+)\*)?.*,(?P<receiver>.+?):/(?P<time>\d{6})+(h|z)(?P<latitude>\d{4}\.\d{2})(?P<latitude_sign>N|S)(?P<symbol_table>.)(?P<longitude>\d{5}\.\d{2})(?P<longitude_sign>E|W)(?P<symbol>.)(?P<course_extension>(?P<course>\d{3})/(?P<ground_speed>\d{3}))?/A=(?P<altitude>\d{6})(?P<pos_extension>\s!W((?P<latitude_enhancement>\d)(?P<longitude_enhancement>\d))!)?(?:\s(?P<comment>.*))?$")
PATTERN_APRS_STATUS = re.compile(r"(?P<callsign>.+?)>(?P<dstcall>[A-Z0-9]+),.+,(?P<receiver>.+?):>(?P<time>\d{6})+h\s(?P<comment>.*)$") PATTERN_APRS_STATUS = re.compile(r"^(?P<callsign>.+?)>(?P<dstcall>[A-Z0-9]+),.+,(?P<receiver>.+?):>(?P<time>\d{6})+h\s(?P<comment>.*)$")
PATTERN_NAVITER_BEACON = re.compile("""
id(?P<details>[\dA-F]{4})(?P<id>[\dA-F]{6})\s
(?P<climb_rate>[+-]\d+)fpm\s
(?P<turn_rate>[+-][\d.]+)rot
""", re.VERBOSE | re.MULTILINE)
# The following regexp patterns are part of the ruby ogn-client. # The following regexp patterns are part of the ruby ogn-client.
# source: https://github.com/svoop/ogn_client-ruby # source: https://github.com/svoop/ogn_client-ruby

Wyświetl plik

@ -1,5 +1,6 @@
import unittest import unittest
import unittest.mock as mock import unittest.mock as mock
import os
from datetime import datetime from datetime import datetime
from time import sleep from time import sleep
@ -9,13 +10,45 @@ from ogn.parser.exceptions import AprsParseError
class TestStringMethods(unittest.TestCase): class TestStringMethods(unittest.TestCase):
def test_valid_beacons(self): def parse_valid_beacon_data_file(self, filename, beacon_type):
with open('tests/valid_beacons.txt') as f: with open(os.path.dirname(__file__) + '/valid_beacon_data/' + filename) as f:
for line in f: for line in f:
if not line[0] == '#': if not line[0] == '#':
aprs = parse_aprs(line, datetime(2015, 4, 10, 17, 0)) aprs = parse_aprs(line, datetime(2015, 4, 10, 17, 0))
self.assertFalse(aprs is None)
if aprs['comment']: if aprs['comment']:
parse_ogn_beacon(aprs['comment']) message = parse_ogn_beacon(aprs['comment'], dstcall=aprs['dstcall'])
self.assertEqual(message['beacon_type'], beacon_type)
def test_aprs_aircraft_beacons(self):
self.parse_valid_beacon_data_file(filename='aprs_aircraft.txt', beacon_type='aircraft_beacon')
def test_aprs_receiver_beacons(self):
self.parse_valid_beacon_data_file(filename='aprs_receiver.txt', beacon_type='receiver_beacon')
def test_ogn_flarm_beacons(self):
self.parse_valid_beacon_data_file(filename='ogn_flarm.txt', beacon_type='aircraft_beacon')
def test_ogn_receiver_beacons(self):
self.parse_valid_beacon_data_file(filename='ogn_receiver.txt', beacon_type='receiver_beacon')
def test_ogn_tracker_beacons(self):
self.parse_valid_beacon_data_file(filename='ogn_tracker.txt', beacon_type='aircraft_beacon')
def test_lt24_beacons(self):
self.parse_valid_beacon_data_file(filename='lt24.txt', beacon_type='lt24_beacon')
def test_naviter_beacons(self):
self.parse_valid_beacon_data_file(filename='naviter.txt', beacon_type='naviter_beacon')
def test_skylines_beacons(self):
self.parse_valid_beacon_data_file(filename='skylines.txt', beacon_type='skylines_beacon')
def test_spider_beacons(self):
self.parse_valid_beacon_data_file(filename='spider.txt', beacon_type='spider_beacon')
def test_spot_beacons(self):
self.parse_valid_beacon_data_file(filename='spot.txt', beacon_type='spot_beacon')
def test_fail_parse_aprs_none(self): def test_fail_parse_aprs_none(self):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):

Wyświetl plik

@ -16,6 +16,7 @@ class TestStringMethods(unittest.TestCase):
message = parse_aprs("FLRDDA5BA>APRS,qAS,LFMX:/160829h4415.41N/00600.03E'342/049/A=005524 this is a comment", message = parse_aprs("FLRDDA5BA>APRS,qAS,LFMX:/160829h4415.41N/00600.03E'342/049/A=005524 this is a comment",
reference_date=datetime(2015, 1, 1, 16, 8, 29)) reference_date=datetime(2015, 1, 1, 16, 8, 29))
self.assertEqual(message['name'], "FLRDDA5BA") self.assertEqual(message['name'], "FLRDDA5BA")
self.assertEqual(message['dstcall'], "APRS")
self.assertEqual(message['receiver_name'], "LFMX") self.assertEqual(message['receiver_name'], "LFMX")
self.assertEqual(message['timestamp'].strftime('%H:%M:%S'), "16:08:29") self.assertEqual(message['timestamp'].strftime('%H:%M:%S'), "16:08:29")
self.assertAlmostEqual(message['latitude'], 44.25683, 5) self.assertAlmostEqual(message['latitude'], 44.25683, 5)
@ -27,6 +28,8 @@ class TestStringMethods(unittest.TestCase):
self.assertAlmostEqual(message['altitude'] * m2feet, 5524, 5) self.assertAlmostEqual(message['altitude'] * m2feet, 5524, 5)
self.assertEqual(message['comment'], "this is a comment") self.assertEqual(message['comment'], "this is a comment")
self.assertEqual(message['aprs_type'], 'position')
def test_v024(self): def test_v024(self):
# higher precision datum format introduced # higher precision datum format introduced
raw_message = "FLRDDA5BA>APRS,qAS,LFMX:/160829h4415.41N/00600.03E'342/049/A=005524 !W26! id21400EA9 -2454fpm +0.9rot 19.5dB 0e -6.6kHz gps1x1 s6.02 h44 rDF0C56" raw_message = "FLRDDA5BA>APRS,qAS,LFMX:/160829h4415.41N/00600.03E'342/049/A=005524 !W26! id21400EA9 -2454fpm +0.9rot 19.5dB 0e -6.6kHz gps1x1 s6.02 h44 rDF0C56"
@ -45,6 +48,8 @@ class TestStringMethods(unittest.TestCase):
self.assertEqual(message['timestamp'].strftime('%H:%M:%S'), "09:34:56") self.assertEqual(message['timestamp'].strftime('%H:%M:%S'), "09:34:56")
self.assertEqual(message['comment'], "this is a comment") self.assertEqual(message['comment'], "this is a comment")
self.assertEqual(message['aprs_type'], 'status')
def test_v026(self): def test_v026(self):
# from 0.2.6 the ogn comment of a receiver beacon is just optional # from 0.2.6 the ogn comment of a receiver beacon is just optional
raw_message = "Ulrichamn>APRS,TCPIP*,qAC,GLIDERN1:/085616h5747.30NI01324.77E&/A=001322" raw_message = "Ulrichamn>APRS,TCPIP*,qAC,GLIDERN1:/085616h5747.30NI01324.77E&/A=001322"
@ -52,6 +57,13 @@ class TestStringMethods(unittest.TestCase):
self.assertEqual(message['comment'], None) self.assertEqual(message['comment'], None)
def test_v026_relay(self):
# beacons can be relayed
raw_message = "FLRFFFFFF>OGNAVI,NAV07220E*,qAS,NAVITER:/092002h1000.00S/01000.00W'000/000/A=003281 !W00! id2820FFFFFF +300fpm +1.7rot"
message = parse_aprs(raw_message, reference_date=datetime(2015, 1, 1, 8, 56, 0))
self.assertEqual(message['relay'], "NAV07220E")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

Wyświetl plik

@ -0,0 +1,30 @@
import unittest
from ogn.parser.utils import ms2fpm
from ogn.parser.parse_naviter import parse
class TestStringMethods(unittest.TestCase):
def test_OGNAVI_1(self):
message = parse("id0440042121 +123fpm +0.5rot")
# id0440042121 == 0b0000 0100 0100 0000 0000 0100 0010 0001 0010 0001
# bit 0: stealth mode
# bit 1: do not track mode
# bits 2-5: aircraft type
# bits 6-11: address type (namespace is extended from 2 to 6 bits to avoid collisions with other tracking providers)
# bits 12-15: reserved for use at a later time
# bits 16-39: device id (24-bit device identifier, same as in APRS header)
self.assertEqual(message['stealth'], False)
self.assertEqual(message['do_not_track'], False)
self.assertEqual(message['aircraft_type'], 1)
self.assertEqual(message['address_type'], 4)
self.assertEqual(message['reserved'], 0)
self.assertEqual(message['address'], "042121")
self.assertAlmostEqual(message['climb_rate'] * ms2fpm, 123, 2)
self.assertEqual(message['turn_rate'], 0.5)
if __name__ == '__main__':
unittest.main()

Wyświetl plik

@ -1,15 +1,15 @@
import unittest import unittest
from ogn.parser.utils import ms2fpm from ogn.parser.utils import ms2fpm
from ogn.parser.parse import parse_ogn_aircraft_beacon from ogn.parser.parse import parse_aircraft_beacon
class TestStringMethods(unittest.TestCase): class TestStringMethods(unittest.TestCase):
def test_invalid_token(self): def test_invalid_token(self):
self.assertEqual(parse_ogn_aircraft_beacon("notAValidToken"), None) self.assertEqual(parse_aircraft_beacon("notAValidToken"), None)
def test_basic(self): def test_basic(self):
aircraft_beacon = parse_ogn_aircraft_beacon("id0ADDA5BA -454fpm -1.1rot 8.8dB 0e +51.2kHz gps4x5 hear1084 hearB597 hearB598") aircraft_beacon = parse_aircraft_beacon("id0ADDA5BA -454fpm -1.1rot 8.8dB 0e +51.2kHz gps4x5 hear1084 hearB597 hearB598")
self.assertEqual(aircraft_beacon['address_type'], 2) self.assertEqual(aircraft_beacon['address_type'], 2)
self.assertEqual(aircraft_beacon['aircraft_type'], 2) self.assertEqual(aircraft_beacon['aircraft_type'], 2)
@ -27,33 +27,33 @@ class TestStringMethods(unittest.TestCase):
self.assertEqual(aircraft_beacon['proximity'][2], 'B598') self.assertEqual(aircraft_beacon['proximity'][2], 'B598')
def test_stealth(self): def test_stealth(self):
aircraft_beacon = parse_ogn_aircraft_beacon("id0ADD1234 -454fpm -1.1rot 8.8dB 0e +51.2kHz gps4x5 hear1084 hearB597 hearB598") aircraft_beacon = parse_aircraft_beacon("id0ADD1234 -454fpm -1.1rot 8.8dB 0e +51.2kHz gps4x5 hear1084 hearB597 hearB598")
self.assertFalse(aircraft_beacon['stealth']) self.assertFalse(aircraft_beacon['stealth'])
aircraft_beacon = parse_ogn_aircraft_beacon("id8ADD1234 -454fpm -1.1rot 8.8dB 0e +51.2kHz gps4x5 hear1084 hearB597 hearB598") aircraft_beacon = parse_aircraft_beacon("id8ADD1234 -454fpm -1.1rot 8.8dB 0e +51.2kHz gps4x5 hear1084 hearB597 hearB598")
self.assertTrue(aircraft_beacon['stealth']) self.assertTrue(aircraft_beacon['stealth'])
def test_v024(self): def test_v024(self):
aircraft_beacon = parse_ogn_aircraft_beacon("id21400EA9 -2454fpm +0.9rot 19.5dB 0e -6.6kHz gps1x1 s6.02 h0A rDF0C56") aircraft_beacon = parse_aircraft_beacon("id21400EA9 -2454fpm +0.9rot 19.5dB 0e -6.6kHz gps1x1 s6.02 h0A rDF0C56")
self.assertEqual(aircraft_beacon['software_version'], 6.02) self.assertEqual(aircraft_beacon['software_version'], 6.02)
self.assertEqual(aircraft_beacon['hardware_version'], 10) self.assertEqual(aircraft_beacon['hardware_version'], 10)
self.assertEqual(aircraft_beacon['real_address'], "DF0C56") self.assertEqual(aircraft_beacon['real_address'], "DF0C56")
def test_v024_ogn_tracker(self): def test_v024_ogn_tracker(self):
aircraft_beacon = parse_ogn_aircraft_beacon("id07353800 +020fpm -14.0rot FL004.43 38.5dB 0e -2.9kHz") aircraft_beacon = parse_aircraft_beacon("id07353800 +020fpm -14.0rot FL004.43 38.5dB 0e -2.9kHz")
self.assertEqual(aircraft_beacon['flightlevel'], 4.43) self.assertEqual(aircraft_beacon['flightlevel'], 4.43)
def test_v025(self): def test_v025(self):
aircraft_beacon = parse_ogn_aircraft_beacon("id06DDE28D +535fpm +3.8rot 11.5dB 0e -1.0kHz gps2x3 s6.01 h0C +7.4dBm") aircraft_beacon = parse_aircraft_beacon("id06DDE28D +535fpm +3.8rot 11.5dB 0e -1.0kHz gps2x3 s6.01 h0C +7.4dBm")
self.assertEqual(aircraft_beacon['signal_power'], 7.4) self.assertEqual(aircraft_beacon['signal_power'], 7.4)
def test_v026(self): def test_v026(self):
# from 0.2.6 it is sufficent we have only the ID, climb and turn rate or just the ID # from 0.2.6 it is sufficent we have only the ID, climb and turn rate or just the ID
aircraft_beacon_triple = parse_ogn_aircraft_beacon("id093D0930 +000fpm +0.0rot") aircraft_beacon_triple = parse_aircraft_beacon("id093D0930 +000fpm +0.0rot")
aircraft_beacon_single = parse_ogn_aircraft_beacon("id093D0930") aircraft_beacon_single = parse_aircraft_beacon("id093D0930")
self.assertIsNotNone(aircraft_beacon_triple) self.assertIsNotNone(aircraft_beacon_triple)
self.assertIsNotNone(aircraft_beacon_single) self.assertIsNotNone(aircraft_beacon_single)

Wyświetl plik

@ -1,14 +1,14 @@
import unittest import unittest
from ogn.parser.parse import parse_ogn_receiver_beacon from ogn.parser.parse import parse_receiver_beacon
class TestStringMethods(unittest.TestCase): class TestStringMethods(unittest.TestCase):
def test_fail_validation(self): def test_fail_validation(self):
self.assertEqual(parse_ogn_receiver_beacon("notAValidToken"), None) self.assertEqual(parse_receiver_beacon("notAValidToken"), None)
def test_v021(self): def test_v021(self):
receiver_beacon = parse_ogn_receiver_beacon("v0.2.1 CPU:0.8 RAM:25.6/458.9MB NTP:0.1ms/+2.3ppm +51.9C RF:+26-1.4ppm/-0.25dB") receiver_beacon = parse_receiver_beacon("v0.2.1 CPU:0.8 RAM:25.6/458.9MB NTP:0.1ms/+2.3ppm +51.9C RF:+26-1.4ppm/-0.25dB")
self.assertEqual(receiver_beacon['version'], "0.2.1") self.assertEqual(receiver_beacon['version'], "0.2.1")
self.assertEqual(receiver_beacon['cpu_load'], 0.8) self.assertEqual(receiver_beacon['cpu_load'], 0.8)
@ -23,17 +23,17 @@ class TestStringMethods(unittest.TestCase):
self.assertEqual(receiver_beacon['rec_input_noise'], -0.25) self.assertEqual(receiver_beacon['rec_input_noise'], -0.25)
def test_v022(self): def test_v022(self):
receiver_beacon = parse_ogn_receiver_beacon("v0.2.2.x86 CPU:0.5 RAM:669.9/887.7MB NTP:1.0ms/+6.2ppm +52.0C RF:+0.06dB") receiver_beacon = parse_receiver_beacon("v0.2.2.x86 CPU:0.5 RAM:669.9/887.7MB NTP:1.0ms/+6.2ppm +52.0C RF:+0.06dB")
self.assertEqual(receiver_beacon['platform'], 'x86') self.assertEqual(receiver_beacon['platform'], 'x86')
def test_v025(self): def test_v025(self):
receiver_beacon = parse_ogn_receiver_beacon("v0.2.5.RPI-GPU CPU:0.8 RAM:287.3/458.7MB NTP:1.0ms/-6.4ppm 5.016V 0.534A +51.9C RF:+55+0.4ppm/-0.67dB/+10.8dB@10km[57282]") receiver_beacon = parse_receiver_beacon("v0.2.5.RPI-GPU CPU:0.8 RAM:287.3/458.7MB NTP:1.0ms/-6.4ppm 5.016V 0.534A +51.9C RF:+55+0.4ppm/-0.67dB/+10.8dB@10km[57282]")
self.assertEqual(receiver_beacon['voltage'], 5.016) self.assertEqual(receiver_beacon['voltage'], 5.016)
self.assertEqual(receiver_beacon['amperage'], 0.534) self.assertEqual(receiver_beacon['amperage'], 0.534)
self.assertEqual(receiver_beacon['senders_signal'], 10.8) self.assertEqual(receiver_beacon['senders_signal'], 10.8)
self.assertEqual(receiver_beacon['senders_messages'], 57282) self.assertEqual(receiver_beacon['senders_messages'], 57282)
receiver_beacon = parse_ogn_receiver_beacon("v0.2.5.ARM CPU:0.4 RAM:638.0/970.5MB NTP:0.2ms/-1.1ppm +65.5C 14/16Acfts[1h] RF:+45+0.0ppm/+3.88dB/+24.0dB@10km[143717]/+26.7dB@10km[68/135]") receiver_beacon = parse_receiver_beacon("v0.2.5.ARM CPU:0.4 RAM:638.0/970.5MB NTP:0.2ms/-1.1ppm +65.5C 14/16Acfts[1h] RF:+45+0.0ppm/+3.88dB/+24.0dB@10km[143717]/+26.7dB@10km[68/135]")
self.assertEqual(receiver_beacon['senders_visible'], 14) self.assertEqual(receiver_beacon['senders_visible'], 14)
self.assertEqual(receiver_beacon['senders_total'], 16) self.assertEqual(receiver_beacon['senders_total'], 16)
self.assertEqual(receiver_beacon['senders_signal'], 24.0) self.assertEqual(receiver_beacon['senders_signal'], 24.0)

Wyświetl plik

@ -0,0 +1,15 @@
# Until OGN software 0.2.6 all beacons (flarms, ogn trackers and receivers) have the dstcall "APRS"
# These are example beacons for flarms and ogn trackers
#
FLRDDA5BA>APRS,qAS,LFMX:/165829h4415.41N/00600.03E'342/049/A=005524 id0ADDA5BA -454fpm -1.1rot 8.8dB 0e +51.2kHz gps4x5
ICA4B0E3A>APRS,qAS,Letzi:/165319h4711.75N\00802.59E^327/149/A=006498 id154B0E3A -3959fpm +0.5rot 9.0dB 0e -6.3kHz gps1x3
FLRDDB091>APRS,qAS,Letzi:/165831h4740.04N/00806.01EX152/124/A=004881 id06DD8E80 +198fpm +0.0rot 6.5dB 13e +4.0kHz gps3x4
FLRDDDD33>APRS,qAS,LFNF:/165341h4344.27N/00547.41E'/A=000886 id06DDDD33 +020fpm +0.0rot 20.8dB 0e -14.3kHz gps3x4
FLRDDE026>APRS,qAS,LFNF:/165341h4358.58N/00553.89E'204/055/A=005048 id06DDE026 +257fpm +0.1rot 7.2dB 0e -0.8kHz gps4x7
ICA484A9C>APRS,qAS,LFMX:/165341h4403.50N/00559.67E'/A=001460 id05484A9C +000fpm +0.0rot 18.0dB 0e +3.5kHz gps4x7
OGNE95A16>APRS,qAS,Sylwek:/165641h5001.94N/01956.91E'270/004/A=000000 id07E95A16 +000fpm +0.1rot 37.8dB 0e -0.4kHz
ZK-GSC>APRS,qAS,Omarama:/165202h4429.25S/16959.33E'/A=001407 id05C821EA +020fpm +0.0rot 16.8dB 0e -3.1kHz gps1x3 hear1084 hearB597 hearB598
#
# since 0.2.6 a aircraft beacon needs just an ID, climb rate and turn rate or just the ID
ICA3ECE59>APRS,qAS,GLDRTR:/171254h5144.78N/00616.67E'263/000/A=000075 id093D0930 +000fpm +0.0rot
ICA3ECE59>APRS,qAS,GLDRTR:/171254h5144.78N/00616.67E'263/000/A=000075 id053ECE59

Wyświetl plik

@ -1,20 +1,15 @@
# aprsc 2.0.14-g28c5a6a 10 Apr 2015 18:58:47 GMT GLIDERN1 37.187.40.234:14580 # Until OGN software 0.2.6 all beacons (flarms, ogn trackers and receivers) have the dstcall "APRS"
FLRDDA5BA>APRS,qAS,LFMX:/165829h4415.41N/00600.03E'342/049/A=005524 id0ADDA5BA -454fpm -1.1rot 8.8dB 0e +51.2kHz gps4x5 # These are example beacons for receivers
ICA4B0E3A>APRS,qAS,Letzi:/165319h4711.75N\00802.59E^327/149/A=006498 id154B0E3A -3959fpm +0.5rot 9.0dB 0e -6.3kHz gps1x3 #
Lachens>APRS,TCPIP*,qAC,GLIDERN2:/165334h4344.70NI00639.19E&/A=005435 v0.2.1 CPU:0.3 RAM:1764.4/2121.4MB NTP:2.8ms/+4.9ppm +47.0C RF:+0.70dB Lachens>APRS,TCPIP*,qAC,GLIDERN2:/165334h4344.70NI00639.19E&/A=005435 v0.2.1 CPU:0.3 RAM:1764.4/2121.4MB NTP:2.8ms/+4.9ppm +47.0C RF:+0.70dB
LFGU>APRS,TCPIP*,qAC,GLIDERN2:/165556h4907.63NI00706.41E&/A=000833 v0.2.0 CPU:0.9 RAM:281.3/458.9MB NTP:0.5ms/-19.1ppm +53.0C RF:+0.70dB LFGU>APRS,TCPIP*,qAC,GLIDERN2:/165556h4907.63NI00706.41E&/A=000833 v0.2.0 CPU:0.9 RAM:281.3/458.9MB NTP:0.5ms/-19.1ppm +53.0C RF:+0.70dB
FLRDDB091>APRS,qAS,Letzi:/165831h4740.04N/00806.01EX152/124/A=004881 id06DD8E80 +198fpm +0.0rot 6.5dB 13e +4.0kHz gps3x4
LSGS>APRS,TCPIP*,qAC,GLIDERN1:/165345h4613.25NI00719.68E&/A=001581 CPU:0.7 RAM:247.9/456.4MB NTP:0.7ms/-11.4ppm +44.4C RF:+53+71.9ppm/+0.4dB LSGS>APRS,TCPIP*,qAC,GLIDERN1:/165345h4613.25NI00719.68E&/A=001581 CPU:0.7 RAM:247.9/456.4MB NTP:0.7ms/-11.4ppm +44.4C RF:+53+71.9ppm/+0.4dB
FLRDDDD33>APRS,qAS,LFNF:/165341h4344.27N/00547.41E'/A=000886 id06DDDD33 +020fpm +0.0rot 20.8dB 0e -14.3kHz gps3x4
FLRDDE026>APRS,qAS,LFNF:/165341h4358.58N/00553.89E'204/055/A=005048 id06DDE026 +257fpm +0.1rot 7.2dB 0e -0.8kHz gps4x7
ICA484A9C>APRS,qAS,LFMX:/165341h4403.50N/00559.67E'/A=001460 id05484A9C +000fpm +0.0rot 18.0dB 0e +3.5kHz gps4x7
WolvesSW>APRS,TCPIP*,qAC,GLIDERN2:/165343h5232.23NI00210.91W&/A=000377 CPU:1.5 RAM:159.9/458.7MB NTP:6.6ms/-36.7ppm +45.5C RF:+130-0.4ppm/-0.1dB WolvesSW>APRS,TCPIP*,qAC,GLIDERN2:/165343h5232.23NI00210.91W&/A=000377 CPU:1.5 RAM:159.9/458.7MB NTP:6.6ms/-36.7ppm +45.5C RF:+130-0.4ppm/-0.1dB
Oxford>APRS,TCPIP*,qAC,GLIDERN1:/165533h5142.96NI00109.68W&/A=000380 v0.1.3 CPU:0.9 RAM:268.8/458.6MB NTP:0.5ms/-45.9ppm +60.5C RF:+55+2.9ppm/+1.54dB Oxford>APRS,TCPIP*,qAC,GLIDERN1:/165533h5142.96NI00109.68W&/A=000380 v0.1.3 CPU:0.9 RAM:268.8/458.6MB NTP:0.5ms/-45.9ppm +60.5C RF:+55+2.9ppm/+1.54dB
OGNE95A16>APRS,qAS,Sylwek:/165641h5001.94N/01956.91E'270/004/A=000000 id07E95A16 +000fpm +0.1rot 37.8dB 0e -0.4kHz
Salland>APRS,TCPIP*,qAC,GLIDERN2:/165426h5227.93NI00620.03E&/A=000049 v0.2.2 CPU:0.7 RAM:659.3/916.9MB NTP:2.5ms/-75.0ppm RF:+0.41dB Salland>APRS,TCPIP*,qAC,GLIDERN2:/165426h5227.93NI00620.03E&/A=000049 v0.2.2 CPU:0.7 RAM:659.3/916.9MB NTP:2.5ms/-75.0ppm RF:+0.41dB
LSGS>APRS,TCPIP*,qAC,GLIDERN1:/165345h4613.25NI00719.68E&/A=001581 CPU:0.7 RAM:247.9/456.4MB NTP:0.7ms/-11.4ppm +44.4C RF:+53+71.9ppm/+0.4dB LSGS>APRS,TCPIP*,qAC,GLIDERN1:/165345h4613.25NI00719.68E&/A=001581 CPU:0.7 RAM:247.9/456.4MB NTP:0.7ms/-11.4ppm +44.4C RF:+53+71.9ppm/+0.4dB
Drenstein>APRS,TCPIP*,qAC,GLIDERN1:/165011h5147.51NI00744.45E&/A=000213 v0.2.2 CPU:0.8 RAM:695.7/4025.5MB NTP:16000.0ms/+0.0ppm +63.0C Drenstein>APRS,TCPIP*,qAC,GLIDERN1:/165011h5147.51NI00744.45E&/A=000213 v0.2.2 CPU:0.8 RAM:695.7/4025.5MB NTP:16000.0ms/+0.0ppm +63.0C
ZK-GSC>APRS,qAS,Omarama:/165202h4429.25S/16959.33E'/A=001407 id05C821EA +020fpm +0.0rot 16.8dB 0e -3.1kHz gps1x3 hear1084 hearB597 hearB598 #
# since 0.2.5 for receiver information not only the "aprs position" format is used but also the "aprs status" format (without lat/lon/alt informations) # since 0.2.5 for receiver information not only the "aprs position" format is used but also the "aprs status" format (without lat/lon/alt informations)
Cordoba>APRS,TCPIP*,qAC,GLIDERN3:/194847h3112.85SI06409.56W&/A=001712 v0.2.5.ARM CPU:0.4 RAM:755.4/970.8MB NTP:6.7ms/-0.1ppm +45.5C RF:+48+18.3ppm/+3.45dB Cordoba>APRS,TCPIP*,qAC,GLIDERN3:/194847h3112.85SI06409.56W&/A=001712 v0.2.5.ARM CPU:0.4 RAM:755.4/970.8MB NTP:6.7ms/-0.1ppm +45.5C RF:+48+18.3ppm/+3.45dB
Cordoba>APRS,TCPIP*,qAC,GLIDERN3:>194847h v0.2.5.ARM CPU:0.4 RAM:755.4/970.8MB NTP:6.7ms/-0.1ppm +45.5C 0/0Acfts[1h] RF:+48+18.3ppm/+3.45dB/+0.4dB@10km[71]/+0.4dB@10km[1/1] Cordoba>APRS,TCPIP*,qAC,GLIDERN3:>194847h v0.2.5.ARM CPU:0.4 RAM:755.4/970.8MB NTP:6.7ms/-0.1ppm +45.5C 0/0Acfts[1h] RF:+48+18.3ppm/+3.45dB/+0.4dB@10km[71]/+0.4dB@10km[1/1]
@ -26,9 +21,6 @@ CNF3a>APRS,TCPIP*,qAC,GLIDERN3:/042143h4529.25NI07505.65W&/A=000259 v0.2.5.ARM C
CNF3a>APRS,TCPIP*,qAC,GLIDERN3:>042143h v0.2.5.ARM CPU:0.6 RAM:514.6/970.8MB NTP:4.5ms/-1.5ppm +27.2C 0/0Acfts[1h] RF:+0-0.4ppm/+18.69dB/+13.0dB@10km[104282]/+9.7dB@10km[2/3] CNF3a>APRS,TCPIP*,qAC,GLIDERN3:>042143h v0.2.5.ARM CPU:0.6 RAM:514.6/970.8MB NTP:4.5ms/-1.5ppm +27.2C 0/0Acfts[1h] RF:+0-0.4ppm/+18.69dB/+13.0dB@10km[104282]/+9.7dB@10km[2/3]
VITACURA2>APRS,TCPIP*,qAC,GLIDERN3:/042136h3322.81SI07034.95W&/A=002345 v0.2.5.ARM CPU:0.3 RAM:695.0/970.5MB NTP:0.6ms/-5.7ppm +51.5C RF:+0-0.0ppm/+1.32dB VITACURA2>APRS,TCPIP*,qAC,GLIDERN3:/042136h3322.81SI07034.95W&/A=002345 v0.2.5.ARM CPU:0.3 RAM:695.0/970.5MB NTP:0.6ms/-5.7ppm +51.5C RF:+0-0.0ppm/+1.32dB
VITACURA2>APRS,TCPIP*,qAC,GLIDERN3:>042136h v0.2.5.ARM CPU:0.3 RAM:695.0/970.5MB NTP:0.6ms/-5.7ppm +52.1C 0/0Acfts[1h] RF:+0-0.0ppm/+1.32dB/+2.1dB@10km[193897]/+9.0dB@10km[10/20] VITACURA2>APRS,TCPIP*,qAC,GLIDERN3:>042136h v0.2.5.ARM CPU:0.3 RAM:695.0/970.5MB NTP:0.6ms/-5.7ppm +52.1C 0/0Acfts[1h] RF:+0-0.0ppm/+1.32dB/+2.1dB@10km[193897]/+9.0dB@10km[10/20]
### since 0.2.6 #
### ... the ogn comment of a receiver beacon is just optional # since 0.2.6 the ogn comment of a receiver beacon is just optional
Ulrichamn>APRS,TCPIP*,qAC,GLIDERN1:/085616h5747.30NI01324.77E&/A=001322 Ulrichamn>APRS,TCPIP*,qAC,GLIDERN1:/085616h5747.30NI01324.77E&/A=001322
### ... a aircraft beacon needs just an ID, climb rate and turn rate or just the ID
ICA3ECE59>APRS,qAS,GLDRTR:/171254h5144.78N/00616.67E'263/000/A=000075 id093D0930 +000fpm +0.0rot
ICA3ECE59>APRS,qAS,GLDRTR:/171254h5144.78N/00616.67E'263/000/A=000075 id053ECE59

Wyświetl plik

@ -0,0 +1,16 @@
# The following beacons are example for LT24 APRS format
# source: https://github.com/glidernet/ogn-aprs-protocol
#
# the id25387 is the LT24 user ID that is unique.
# GPS means that the coordinates are from the GPS unit of the smartphone vs. the GSM network.
#
FLRDDE48A>OGLT24,qAS,LT24:/102606h4030.47N/00338.38W'000/018/A=002267 id25387 +000fpm GPS
FLRDDE48A>OGLT24,qAS,LT24:/102608h4030.47N/00338.38W'044/018/A=002270 id25387 +000fpm GPS
FLRDDE48A>OGLT24,qAS,LT24:/102611h4030.47N/00338.38W'108/000/A=002280 id25387 +001fpm GPS
FLRDDE48A>OGLT24,qAS,LT24:/102612h4030.47N/00338.38W'000/000/A=002280 id25387 +000fpm GPS
FLRDDE48A>OGLT24,qAS,LT24:/102615h4030.47N/00338.39W'224/003/A=002280 id25387 +000fpm GPS
FLRDDE48A>OGLT24,qAS,LT24:/102616h4030.47N/00338.38W'028/003/A=002250 id25387 -009fpm GPS
FLRDDE48A>OGLT24,qAS,LT24:/102621h4030.47N/00338.38W'142/001/A=002267 id25387 +001fpm GPS
FLRDDE48A>OGLT24,qAS,LT24:/102628h4030.47N/00338.38W'034/000/A=002263 id25387 +000fpm GPS
FLRDDE48A>OGLT24,qAS,LT24:/102717h4030.47N/00338.38W'000/000/A=002263 id25387 +000fpm GPS
FLRDDE48A>OGLT24,qAS,LT24:/110453h4030.47N/00338.38W'154/004/A=002253 id25387 +000fpm GPS

Wyświetl plik

@ -0,0 +1,7 @@
# The following beacons are example for NAVITER's APRS format version OGNAVI-1
# source: https://github.com/glidernet/ogn-aprs-protocol
#
NAV042121>OGNAVI,qAS,NAVITER:/140648h4550.36N/01314.85E'090/152/A=001086 !W47! id0440042121 +000fpm +0.5rot
NAV04220E>OGNAVI,qAS,NAVITER:/140748h4552.27N/01155.61E'090/012/A=006562 !W81! id044004220E +060fpm +1.2rot
NAV07220E>OGNAVI,qAS,NAVITER:/125447h4557.77N/01220.19E'258/056/A=006562 !W76! id1C4007220E +180fpm +0.0rot
FLRFFFFFF>OGNAVI,NAV07220E*,qAS,NAVITER:/092002h1000.00S/01000.00W'000/000/A=003281 !W00! id2820FFFFFF +300fpm +1.7rot

Wyświetl plik

@ -0,0 +1,7 @@
# With OGN software 0.2.7 flarms have the dstcall "OGFLR"
#
FLRDD89C9>OGFLR,qAS,LIDH:/115054h4543.22N/01132.84E'260/072/A=002542 !W10! id06DD89C9 +198fpm -0.8rot 7.0dB 0e +0.7kHz gps2x3
FLRDD98C6>OGFLR,qAS,LIDH:/115054h4543.21N/01132.80E'255/074/A=002535 !W83! id0ADD98C6 +158fpm -1.8rot 10.5dB 0e -0.8kHz gps2x3 s6.09 h02
ICAA8CBA8>OGFLR,qAS,MontCAIO:/231150z4512.12N\01059.03E^192/106/A=009519 !W20! id21A8CBA8 -039fpm +0.0rot 3.5dB 2e -8.7kHz gps1x2 s6.09 h43 rDF0267
ICAA8CBA8>OGFLR,qAS,MontCAIO:/114949h4512.44N\01059.12E^190/106/A=009522 !W33! id21A8CBA8 -039fpm +0.1rot 4.5dB 1e -8.7kHz gps1x2 +14.3dBm
ICA3D1C35>OGFLR,qAS,Padova:/094220h4552.41N/01202.28E'110/099/A=003982 !W96! id053D1C35 -1187fpm +0.0rot 0.8dB 2e +4.5kHz gps1x2 s6.09 h32 rDD09D0

Wyświetl plik

@ -0,0 +1,16 @@
# With OGN software 0.2.7 receivers have the dstcall "OGNSDR"
#
LILH>OGNSDR,TCPIP*,qAC,GLIDERN2:/132201h4457.61NI00900.58E&/A=000423
LILH>OGNSDR,TCPIP*,qAC,GLIDERN2:>132201h v0.2.7.RPI-GPU CPU:0.7 RAM:770.2/968.2MB NTP:1.8ms/-3.3ppm +55.7C 7/8Acfts[1h] RF:+54-1.1ppm/-0.16dB/+7.1dB@10km[19481]/+16.8dB@10km[7/13]
MontCAIO>OGNSDR,TCPIP*,qAC,GLIDERN3:/132231h4427.84NI01009.60E&/A=004822
MontCAIO>OGNSDR,TCPIP*,qAC,GLIDERN3:>132231h v0.2.7.RPI-GPU CPU:0.8 RAM:747.0/970.5MB NTP:2.8ms/-1.0ppm +73.1C 5/5Acfts[1h] RF:+69+1.3ppm/+3.53dB/+16.9dB@10km[7697]/+23.7dB@10km[3/6]
Padova>OGNSDR,TCPIP*,qAC,GLIDERN1:/132326h4525.38NI01156.29E&/A=000069
Padova>OGNSDR,TCPIP*,qAC,GLIDERN1:>132326h v0.2.7.RPI-GPU CPU:0.5 RAM:605.1/970.5MB NTP:0.5ms/-2.0ppm +65.5C 1/1Acfts[1h] RF:+0-1.1ppm/+13.97dB/+17.1dB@10km[6524]/+19.9dB@10km[5/9]
LIDH>OGNSDR,TCPIP*,qAC,GLIDERN1:/132447h4540.89NI01129.65E&/A=000328
LIDH>OGNSDR,TCPIP*,qAC,GLIDERN1:>132447h v0.2.7.RPI-GPU CPU:0.4 RAM:593.4/970.5MB NTP:3.7ms/-7.6ppm +67.7C 5/5Acfts[1h] RF:+61+1.0ppm/+12.63dB/+3.7dB@10km[27143]/+3.3dB@10km[3/6]
LZHL>OGNSDR,TCPIP*,qAC,GLIDERN3:/132457h4849.09NI01708.30E&/A=000528
LZHL>OGNSDR,TCPIP*,qAC,GLIDERN3:>132457h v0.2.7.arm CPU:0.9 RAM:75.3/253.6MB NTP:2.0ms/-15.2ppm +0.1C 2/2Acfts[1h] RF:+77+1.7ppm/+2.34dB/+6.5dB@10km[5411]/+10.1dB@10km[3/5]
BELG>OGNSDR,TCPIP*,qAC,GLIDERN3:/132507h4509.60NI00919.20E&/A=000246
BELG>OGNSDR,TCPIP*,qAC,GLIDERN3:>132507h v0.2.7.RPI-GPU CPU:1.2 RAM:35.7/455.2MB NTP:2.5ms/-5.3ppm +67.0C 1/1Acfts[1h] RF:+79+8.8ppm/+4.97dB/-0.0dB@10km[299]/+4.9dB@10km[2/3]
Saleve>OGNSDR,TCPIP*,qAC,GLIDERN1:/132624h4607.70NI00610.41E&/A=004198 Antenna: chinese, on a pylon, 20 meter above ground
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]

Wyświetl plik

@ -0,0 +1,9 @@
# With OGN software 0.2.7 ogn tracker have the dstcall "OGNTRK"
#
OGN3FC859>OGNTRK,qAS,LZHL:>093215h h00 v00 9sat/1 164m 1002.6hPa +20.2degC 0% 3.34V 14/-110.5dBm 1/min
OGN2FD00F>OGNTRK,qAS,LZHL:/093213h4848.78N/01708.32E'000/000/A=000538 !W12! id072FD00F -058fpm +0.0rot FL003.12 32.8dB 0e -0.8kHz gps3x5
FLRDD9C70>OGNTRK,OGN2FD00F*,qAS,LZHL:/093214h4848.77N/01708.33E'000/000/A=000515 !W56! id06DD9C70 -019fpm +0.0rot 32.2dB 0e -0.8kHz gps2x3
FLRDD9C70>OGNTRK,OGN2FD00F*,qAS,LZHL:/093021h4848.77N/01708.33E'000/000/A=000518 !W66! id06DD9C70 -019fpm +0.0rot 29.0dB 0e -0.8kHz gps2x3 s6.09 h03
OGN03AF2A>OGNTRK,qAS,LZHL:/092912h4848.77N/01708.33E'000/000/A=000535 !W53! id0703AF2A +000fpm +0.0rot FL003.15 4.5dB 1e -0.1kHz gps4x5 -11.2dBm
OGN2FD00F>OGNTRK,qAS,LZHL:>092840h h00 v00 11sat/2 165m 1001.9hPa +27.1degC 0% 3.28V 14/-111.5dBm 127/min
FLRDD9C70>OGNTRK,RELAY*,qAS,LZHL:/094124h4848.78N/01708.33E'000/000/A=000397 !W15! id06DD9C70 +099fpm +0.0rot 24.5dB 0e -1.4kHz gps10x15

Wyświetl plik

@ -0,0 +1,6 @@
# The following beacons are example for Skylines (XCsoar) APRS format
# source: https://github.com/glidernet/ogn-aprs-protocol
#
# The id2816 is the Pilot ID from Skylines (XCsoar) and it is unique within the skyline system
#
FLRDDDD78>OGSKYL,qAS,SKYLINES:/134403h4225.90N/00144.83E'000/000/A=008438 id2816 +000fpm

Wyświetl plik

@ -0,0 +1,23 @@
# The following beacons are example for Spider APRS format
# source: https://github.com/glidernet/ogn-aprs-protocol
#
# id3003... is the unique identifier from the SPIDER server
# LWE is the registration within the SPIDER system
# 3D is the quality of the signal 3D vs. 2D
#
FLRDDF944>OGSPID,qAS,SPIDER:/190930h3322.78S/07034.60W'000/000/A=002263 id300234010617040 +19dB LWE 3D
FLRDDF944>OGSPID,qAS,SPIDER:/190930h3322.78S/07034.60W'000/000/A=002263 id300234010617040 +19dB LWE 3D
FLRDDF944>OGSPID,qAS,SPIDER:/192430h3322.78S/07034.61W'000/000/A=002250 id300234010617040 +12dB LWE 3D
FLRDDF944>OGSPID,qAS,SPIDER:/193930h3322.10S/07034.26W'273/027/A=004071 id300234010617040 +9dB LWE 3D
FLRDDF944>OGSPID,qAS,SPIDER:/195430h3322.82S/07034.90W'000/000/A=002217 id300234010617040 +10dB LWE 3D
FLRDDF944>OGSPID,qAS,SPIDER:/193930h3322.78S/07034.60W'348/000/A=002286 id300234010617040 +12dB LWE 3D
FLRDDF944>OGSPID,qAS,SPIDER:/195430h3323.16S/07037.68W'302/034/A=003316 id300234010617040 +10dB LWE 3D
FLRDDF944>OGSPID,qAS,SPIDER:/195430h3323.16S/07037.68W'302/034/A=003316 id300234010617040 +10dB LWE 3D
FLRDDF944>OGSPID,qAS,SPIDER:/200930h3319.13S/07036.12W'128/031/A=005482 id300234010617040 +15dB LWE 3D
FLRDDF944>OGSPID,qAS,SPIDER:/200930h3319.13S/07036.12W'128/031/A=005482 id300234010617040 +15dB LWE 3D
FLRDDF944>OGSPID,qAS,SPIDER:/202430h3314.92S/07032.08W'138/032/A=006453 id300234010617040 +9dB LWE 3D
FLRDDF944>OGSPID,qAS,SPIDER:/203930h3321.38S/07027.29W'104/034/A=006272 id300234010617040 +8dB LWE 3D
FLRDDF944>OGSPID,qAS,SPIDER:/205430h3322.13S/07033.53W'296/031/A=003927 id300234010617040 +7dB LWE 3D
FLRDDF944>OGSPID,qAS,SPIDER:/210930h3322.05S/07035.74W'165/030/A=005187 id300234010617040 +8dB LWE 3D
FLRDDF944>OGSPID,qAS,SPIDER:/212430h3322.02S/07036.14W'281/028/A=004550 id300234010617040 +7dB LWE 3D
FLRDDF944>OGSPID,qAS,SPIDER:/213930h3322.17S/07033.97W'332/028/A=003428 id300234010617040 +7dB LWE 3D

Wyświetl plik

@ -0,0 +1,10 @@
# The following beacons are example for SPOT APRS format
# source: https://github.com/glidernet/ogn-aprs-protocol
#
# id0-28... is a unique ID within the SPOT system.
# SPOT2 is the Spot model
# GOOD is the battery status or some other help messages.
#
ICA3E7540>OGSPOT,qAS,SPOT:/161427h1448.35S/04610.86W'000/000/A=008677 id0-2860357 SPOT3 GOOD
ICA3E7540>OGSPOT,qAS,SPOT:/162923h1431.99S/04604.33W'000/000/A=006797 id0-2860357 SPOT3 GOOD
ICA3E7540>OGSPOT,qAS,SPOT:/163421h1430.38S/04604.43W'000/000/A=007693 id0-2860357 SPOT3 GOOD