From faa73997d75d0fd4d55e28f97648507e6eda92fa Mon Sep 17 00:00:00 2001 From: lemoidului Date: Sat, 1 May 2021 02:02:02 +0200 Subject: [PATCH 1/3] add safesky parser --- ogn/parser/aprs_comment/safesky_parser.py | 25 +++++++++++++++++++++++ ogn/parser/parse.py | 2 ++ ogn/parser/pattern.py | 6 ++++++ tests/parser/test_parse_safesky.py | 17 +++++++++++++++ 4 files changed, 50 insertions(+) create mode 100644 ogn/parser/aprs_comment/safesky_parser.py create mode 100644 tests/parser/test_parse_safesky.py diff --git a/ogn/parser/aprs_comment/safesky_parser.py b/ogn/parser/aprs_comment/safesky_parser.py new file mode 100644 index 0000000..f56c7ca --- /dev/null +++ b/ogn/parser/aprs_comment/safesky_parser.py @@ -0,0 +1,25 @@ +from ogn.parser.utils import FPM_TO_MS +from ogn.parser.pattern import PATTERN_SAFESKY_POSITION_COMMENT + +from .base import BaseParser + + +class SafeskyParser(BaseParser): + def __init__(self): + self.beacon_type = 'safesky' + self.position_pattern = PATTERN_SAFESKY_POSITION_COMMENT + + def parse_position(self, aprs_comment): + match = self.position_pattern.match(aprs_comment) + result = dict() + result.update( + {'safesky_id': match.group('safesky_id'), + 'climb_rate': int(match.group('climb_rate')) * FPM_TO_MS if match.group('climb_rate') else None}) + if match.group('gps_quality'): + result.update({ + 'gps_quality': { + 'horizontal': int(match.group('gps_quality_horizontal')), + 'vertical': int(match.group('gps_quality_vertical')) + } + }) + return result diff --git a/ogn/parser/parse.py b/ogn/parser/parse.py index 8f26570..b59db08 100644 --- a/ogn/parser/parse.py +++ b/ogn/parser/parse.py @@ -16,6 +16,7 @@ from ogn.parser.aprs_comment.skylines_parser import SkylinesParser from ogn.parser.aprs_comment.spider_parser import SpiderParser from ogn.parser.aprs_comment.spot_parser import SpotParser from ogn.parser.aprs_comment.inreach_parser import InreachParser +from ogn.parser.aprs_comment.safesky_parser import SafeskyParser from ogn.parser.aprs_comment.generic_parser import GenericParser positions = {} @@ -155,6 +156,7 @@ dstcall_parser_mapping = {'APRS': OgnParser(), 'OGSKYL': SkylinesParser(), 'OGSPID': SpiderParser(), 'OGSPOT': SpotParser(), + 'OGNSKY': SafeskyParser(), 'GENERIC': GenericParser(beacon_type='unknown'), } diff --git a/ogn/parser/pattern.py b/ogn/parser/pattern.py index cd38500..1b65459 100644 --- a/ogn/parser/pattern.py +++ b/ogn/parser/pattern.py @@ -82,6 +82,12 @@ PATTERN_TRACKER_POSITION_COMMENT = re.compile(r""" (?:(?P[+-][\d.]+)dBm\s?)? """, re.VERBOSE | re.MULTILINE) +PATTERN_SAFESKY_POSITION_COMMENT = re.compile(r""" + id(?P[A-F0-9]{8})\s + (?:(?P[+-]\d+?)fpm\s)? + (?:gps(?P(?P(\d+))x(?P(\d+)))?)? +""", re.VERBOSE | re.MULTILINE) + PATTERN_TRACKER_STATUS_COMMENT = re.compile(r""" h(?P[\d]{2})\s v(?P[\d]{2})\s? diff --git a/tests/parser/test_parse_safesky.py b/tests/parser/test_parse_safesky.py new file mode 100644 index 0000000..8ce0368 --- /dev/null +++ b/tests/parser/test_parse_safesky.py @@ -0,0 +1,17 @@ +import unittest + +from ogn.parser.utils import FPM_TO_MS +from ogn.parser.aprs_comment.safesky_parser import SafeskyParser + + +class TestStringMethods(unittest.TestCase): + def test_position_comment(self): + # "SKY3E5906>OGNSKY,qAS,SafeSky:/072555h5103.47N/00524.81E'065/031/A=001250 !W05! id1C3E5906 +010fpm gps6x1" + message = SafeskyParser().parse_position("id1C3E5906 +010fpm gps6x1") + self.assertEqual(message['safesky_id'], '1C3E5906') + self.assertAlmostEqual(message['climb_rate'], 10 * FPM_TO_MS, 2) + self.assertEqual(message['gps_quality'], {'horizontal': 6, 'vertical': 1}) + + +if __name__ == '__main__': + unittest.main() From 68f8b9b3a7e7a0a6ea2a704f553f6c425eb8cbab Mon Sep 17 00:00:00 2001 From: lemoidului Date: Sat, 1 May 2021 17:51:31 +0200 Subject: [PATCH 2/3] add safesky parser comment details --- ogn/parser/aprs_comment/safesky_parser.py | 11 +++++++++-- ogn/parser/pattern.py | 2 +- tests/parser/test_parse_safesky.py | 4 +++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/ogn/parser/aprs_comment/safesky_parser.py b/ogn/parser/aprs_comment/safesky_parser.py index f56c7ca..5c6c05b 100644 --- a/ogn/parser/aprs_comment/safesky_parser.py +++ b/ogn/parser/aprs_comment/safesky_parser.py @@ -12,9 +12,16 @@ class SafeskyParser(BaseParser): def parse_position(self, aprs_comment): match = self.position_pattern.match(aprs_comment) result = dict() + if match.group('details'): + result.update({ + 'address_type': int(match.group('details'), 16) & 0b00000011, + 'aircraft_type': (int(match.group('details'), 16) & 0b00111100) >> 2, + 'no-tracking': (int(match.group('details'), 16) & 0b01000000) >> 6 == 1, + 'stealth': (int(match.group('details'), 16) & 0b10000000) >> 7 == 1, + 'address': match.group('address'), + }) result.update( - {'safesky_id': match.group('safesky_id'), - 'climb_rate': int(match.group('climb_rate')) * FPM_TO_MS if match.group('climb_rate') else None}) + {'climb_rate': int(match.group('climb_rate')) * FPM_TO_MS if match.group('climb_rate') else None}) if match.group('gps_quality'): result.update({ 'gps_quality': { diff --git a/ogn/parser/pattern.py b/ogn/parser/pattern.py index 1b65459..151a5d5 100644 --- a/ogn/parser/pattern.py +++ b/ogn/parser/pattern.py @@ -83,7 +83,7 @@ PATTERN_TRACKER_POSITION_COMMENT = re.compile(r""" """, re.VERBOSE | re.MULTILINE) PATTERN_SAFESKY_POSITION_COMMENT = re.compile(r""" - id(?P[A-F0-9]{8})\s + id(?P
[\dA-F]{2})(?P
[\dA-F]{6}?)\s? (?:(?P[+-]\d+?)fpm\s)? (?:gps(?P(?P(\d+))x(?P(\d+)))?)? """, re.VERBOSE | re.MULTILINE) diff --git a/tests/parser/test_parse_safesky.py b/tests/parser/test_parse_safesky.py index 8ce0368..b3f1abb 100644 --- a/tests/parser/test_parse_safesky.py +++ b/tests/parser/test_parse_safesky.py @@ -8,7 +8,9 @@ class TestStringMethods(unittest.TestCase): def test_position_comment(self): # "SKY3E5906>OGNSKY,qAS,SafeSky:/072555h5103.47N/00524.81E'065/031/A=001250 !W05! id1C3E5906 +010fpm gps6x1" message = SafeskyParser().parse_position("id1C3E5906 +010fpm gps6x1") - self.assertEqual(message['safesky_id'], '1C3E5906') + self.assertEqual(message['address'], '3E5906') + self.assertEqual(message['address_type'], 0) + self.assertEqual(message['aircraft_type'], 7) self.assertAlmostEqual(message['climb_rate'], 10 * FPM_TO_MS, 2) self.assertEqual(message['gps_quality'], {'horizontal': 6, 'vertical': 1}) From b51a3e95e6c961b5d2f73012cb21d5efcc65912b Mon Sep 17 00:00:00 2001 From: lemoidului Date: Sat, 1 May 2021 18:11:21 +0200 Subject: [PATCH 3/3] add safesky stealth test in unit test --- tests/parser/test_parse_safesky.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/parser/test_parse_safesky.py b/tests/parser/test_parse_safesky.py index b3f1abb..7b6444e 100644 --- a/tests/parser/test_parse_safesky.py +++ b/tests/parser/test_parse_safesky.py @@ -11,6 +11,7 @@ class TestStringMethods(unittest.TestCase): self.assertEqual(message['address'], '3E5906') self.assertEqual(message['address_type'], 0) self.assertEqual(message['aircraft_type'], 7) + self.assertFalse(message['stealth']) self.assertAlmostEqual(message['climb_rate'], 10 * FPM_TO_MS, 2) self.assertEqual(message['gps_quality'], {'horizontal': 6, 'vertical': 1})