kopia lustrzana https://github.com/glidernet/python-ogn-client
Added support for OGFLYM beacons (fixes #63)
rodzic
706a725305
commit
b7f51b92f8
|
@ -1,6 +1,8 @@
|
||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
## 0.9.4: unreleased
|
## 0.9.4: unreleased
|
||||||
- parser: Added support for OGINREACH (Garmin inReach) beacons
|
- parser: Added support for OGINREACH (Garmin inReach) beacons
|
||||||
|
- parser: Added support for OGFLYM (Flymaster) beacons
|
||||||
|
- parser: Added support for comments in tracker beacons (OGNTRK)
|
||||||
|
|
||||||
## 0.9.3: - 2019-06-03
|
## 0.9.3: - 2019-06-03
|
||||||
- parser: Added Generic parser for unknown formats
|
- parser: Added Generic parser for unknown formats
|
||||||
|
|
|
@ -2,8 +2,8 @@ from .base import BaseParser
|
||||||
|
|
||||||
|
|
||||||
class GenericParser(BaseParser):
|
class GenericParser(BaseParser):
|
||||||
def __init__(self):
|
def __init__(self, beacon_type='unknown'):
|
||||||
self.beacon_type = 'generic'
|
self.beacon_type = beacon_type
|
||||||
|
|
||||||
def parse_position(self, aprs_comment):
|
def parse_position(self, aprs_comment):
|
||||||
return {'comment': aprs_comment}
|
return {'comment': aprs_comment}
|
||||||
|
|
|
@ -56,7 +56,7 @@ def parse_aprs(message, reference_timestamp=None):
|
||||||
else:
|
else:
|
||||||
match = re.search(PATTERN_APRS, message)
|
match = re.search(PATTERN_APRS, message)
|
||||||
if match:
|
if match:
|
||||||
aprs_type = 'position' if match.group('aprs_type') == '/' else 'status'
|
aprs_type = 'position' if match.group('aprs_type') == '/' else 'status' if match.group('aprs_type') == '>' else 'unknown'
|
||||||
result.update({'aprs_type': aprs_type})
|
result.update({'aprs_type': aprs_type})
|
||||||
aprs_body = match.group('aprs_body')
|
aprs_body = match.group('aprs_body')
|
||||||
if aprs_type == 'position':
|
if aprs_type == 'position':
|
||||||
|
@ -90,7 +90,7 @@ def parse_aprs(message, reference_timestamp=None):
|
||||||
'timestamp': createTimestamp(match_status.group('time'), reference_timestamp),
|
'timestamp': createTimestamp(match_status.group('time'), reference_timestamp),
|
||||||
'comment': match_status.group('comment') if match_status.group('comment') else ""})
|
'comment': match_status.group('comment') if match_status.group('comment') else ""})
|
||||||
else:
|
else:
|
||||||
raise AprsParseError(message)
|
raise NotImplementedError(message)
|
||||||
else:
|
else:
|
||||||
raise AprsParseError(message)
|
raise AprsParseError(message)
|
||||||
|
|
||||||
|
@ -102,13 +102,14 @@ dstcall_parser_mapping = {'APRS': OgnParser(),
|
||||||
'OGFLR': FlarmParser(),
|
'OGFLR': FlarmParser(),
|
||||||
'OGNTRK': TrackerParser(),
|
'OGNTRK': TrackerParser(),
|
||||||
'OGNSDR': ReceiverParser(),
|
'OGNSDR': ReceiverParser(),
|
||||||
|
'OGFLYM': GenericParser(beacon_type='flymaster'),
|
||||||
'OGINREACH': InreachParser(),
|
'OGINREACH': InreachParser(),
|
||||||
'OGLT24': LT24Parser(),
|
'OGLT24': LT24Parser(),
|
||||||
'OGNAVI': NaviterParser(),
|
'OGNAVI': NaviterParser(),
|
||||||
'OGSKYL': SkylinesParser(),
|
'OGSKYL': SkylinesParser(),
|
||||||
'OGSPID': SpiderParser(),
|
'OGSPID': SpiderParser(),
|
||||||
'OGSPOT': SpotParser(),
|
'OGSPOT': SpotParser(),
|
||||||
'GENERIC': GenericParser(),
|
'GENERIC': GenericParser(beacon_type='unknown'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import re
|
import re
|
||||||
|
|
||||||
PATTERN_APRS = re.compile(r"^(?P<callsign>.+?)>(?P<dstcall>[A-Z0-9]+),((?P<relay>[A-Za-z0-9]+)\*)?.*,(?P<receiver>.+?):(?P<aprs_type>(/|>))(?P<aprs_body>.*)$")
|
PATTERN_APRS = re.compile(r"^(?P<callsign>.+?)>(?P<dstcall>[A-Z0-9]+),((?P<relay>[A-Za-z0-9]+)\*)?.*,(?P<receiver>.+?):(?P<aprs_type>(.))(?P<aprs_body>.*)$")
|
||||||
PATTERN_APRS_POSITION = re.compile(r"^(?P<time>(([0-1]\d|2[0-3])[0-5]\d[0-5]\dh|([0-2]\d|3[0-1])([0-1]\d|2[0-3])[0-5]\dz))(?P<latitude>9000\.00|[0-8]\d{3}\.\d{2})(?P<latitude_sign>N|S)(?P<symbol_table>.)(?P<longitude>18000\.00|1[0-7]\d{3}\.\d{2}|0\d{4}\.\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{5}|\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<time>(([0-1]\d|2[0-3])[0-5]\d[0-5]\dh|([0-2]\d|3[0-1])([0-1]\d|2[0-3])[0-5]\dz))(?P<latitude>9000\.00|[0-8]\d{3}\.\d{2})(?P<latitude_sign>N|S)(?P<symbol_table>.)(?P<longitude>18000\.00|1[0-7]\d{3}\.\d{2}|0\d{4}\.\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{5}|\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<time>(([0-1]\d|2[0-3])[0-5]\d[0-5]\dh|([0-2]\d|3[0-1])([0-1]\d|2[0-3])[0-5]\dz))\s(?P<comment>.*)$")
|
PATTERN_APRS_STATUS = re.compile(r"^(?P<time>(([0-1]\d|2[0-3])[0-5]\d[0-5]\dh|([0-2]\d|3[0-1])([0-1]\d|2[0-3])[0-5]\dz))\s(?P<comment>.*)$")
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,9 @@ class TestStringMethods(unittest.TestCase):
|
||||||
def test_tracker_beacons(self):
|
def test_tracker_beacons(self):
|
||||||
self.parse_valid_beacon_data_file(filename='tracker.txt', beacon_type='tracker')
|
self.parse_valid_beacon_data_file(filename='tracker.txt', beacon_type='tracker')
|
||||||
|
|
||||||
|
def test_flymaster_beacons(self):
|
||||||
|
self.parse_valid_beacon_data_file(filename='flymaster.txt', beacon_type='flymaster')
|
||||||
|
|
||||||
def test_inreach_beacons(self):
|
def test_inreach_beacons(self):
|
||||||
self.parse_valid_beacon_data_file(filename='inreach.txt', beacon_type='inreach')
|
self.parse_valid_beacon_data_file(filename='inreach.txt', beacon_type='inreach')
|
||||||
|
|
||||||
|
@ -59,7 +62,8 @@ class TestStringMethods(unittest.TestCase):
|
||||||
|
|
||||||
def test_generic_beacons(self):
|
def test_generic_beacons(self):
|
||||||
message = parse("EPZR>WTFDSTCALL,TCPIP*,qAC,GLIDERN1:>093456h this is a comment")
|
message = parse("EPZR>WTFDSTCALL,TCPIP*,qAC,GLIDERN1:>093456h this is a comment")
|
||||||
self.assertEqual(message['beacon_type'], 'generic')
|
self.assertEqual(message['beacon_type'], 'unknown')
|
||||||
|
self.assertEqual(message['comment'], "this is a comment")
|
||||||
|
|
||||||
def test_fail_parse_aprs_none(self):
|
def test_fail_parse_aprs_none(self):
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
# The following beacons are example for Flymaster APRS format
|
||||||
|
# source: https://github.com/glidernet/ogn-aprs-protocol
|
||||||
|
#
|
||||||
|
FMT924469>OGFLYM,qAS,FLYMASTER:/155232h3720.70N/00557.97W^222/092/A=000029 !W52!
|
||||||
|
FMT003549>OGFLYM,qAS,FLYMASTER:/155231h3751.35N/00126.13W^270/022/A=001430 !W14!
|
||||||
|
FMT001300>OGFLYM,qAS,FLYMASTER:/155249h3706.99N/00807.27W^178/000/A=000131 !W86!
|
||||||
|
FMT798890>OGFLYM,qAS,FLYMASTER:/155256h3720.49N/00558.27W^234/086/A=000009 !W00!
|
||||||
|
FMT549112>OGFLYM,qAS,FLYMASTER:/155256h3720.48N/00558.27W^234/086/A=000032 !W81!
|
||||||
|
FMT148694>OGFLYM,qAS,FLYMASTER:/155244h3720.58N/00558.11W^226/087/A=000019 !W81!
|
||||||
|
FMT842374>OGFLYM,qAS,FLYMASTER:/155302h3720.44N/00558.34W^236/082/A=000013 !W88!
|
||||||
|
FMT003725>OGFLYM,qAS,FLYMASTER:/155304h3652.58N/00255.91W^346/000/A=001968 !W66!
|
||||||
|
FMT924469>OGFLYM,qAS,FLYMASTER:/155306h3720.42N/00558.40W^250/081/A=000013 !W85!
|
||||||
|
FMT003549>OGFLYM,qAS,FLYMASTER:/155316h3751.64N/00126.08W^020/048/A=001322 !W98!
|
||||||
|
FMT148694>OGFLYM,qAS,FLYMASTER:/155318h3720.42N/00558.59W^282/088/A=000026 !W85!
|
||||||
|
FMT549112>OGFLYM,qAS,FLYMASTER:/155328h3720.45N/00558.75W^282/079/A=000032 !W60!
|
||||||
|
FMT842374>OGFLYM,qAS,FLYMASTER:/155335h3720.47N/00558.84W^280/078/A=000019 !W68!
|
||||||
|
FMT001300>OGFLYM,qAS,FLYMASTER:/155339h3706.99N/00807.27W^178/000/A=000131 !W95!
|
||||||
|
FMT798890>OGFLYM,qAS,FLYMASTER:/155338h3720.48N/00558.89W^282/080/A=000019 !W46!
|
||||||
|
FMT924469>OGFLYM,qAS,FLYMASTER:/155341h3720.49N/00558.93W^282/075/A=000009 !W27!
|
||||||
|
FMT003725>OGFLYM,qAS,FLYMASTER:/155346h3652.58N/00255.91W^346/000/A=001971 !W75!
|
||||||
|
FMT003549>OGFLYM,qAS,FLYMASTER:/155349h3751.76N/00125.91W^064/032/A=001414 !W27!
|
||||||
|
FMT148694>OGFLYM,qAS,FLYMASTER:/155352h3720.51N/00559.02W^292/026/A=000026 !W48!
|
||||||
|
FMT549112>OGFLYM,qAS,FLYMASTER:/155400h3720.52N/00559.06W^298/031/A=000045 !W74!
|
||||||
|
FMT842374>OGFLYM,qAS,FLYMASTER:/155409h3720.54N/00559.10W^302/019/A=000042 !W70!
|
||||||
|
FMT798890>OGFLYM,qAS,FLYMASTER:/155412h3720.54N/00559.10W^304/001/A=000026 !W96!
|
||||||
|
FMT924469>OGFLYM,qAS,FLYMASTER:/155415h3720.54N/00559.10W^000/001/A=000022 !W95!
|
||||||
|
FMT003725>OGFLYM,qAS,FLYMASTER:/155420h3652.58N/00255.91W^346/000/A=001971 !W75!
|
||||||
|
FMT003549>OGFLYM,qAS,FLYMASTER:/155422h3751.81N/00125.73W^220/002/A=001584 !W42!
|
||||||
|
FMT001300>OGFLYM,qAS,FLYMASTER:/155429h3706.99N/00807.27W^178/000/A=000131 !W96!
|
||||||
|
FMT148694>OGFLYM,qAS,FLYMASTER:/155435h3720.58N/00559.16W^314/017/A=000039 !W83!
|
||||||
|
FMT549112>OGFLYM,qAS,FLYMASTER:/155443h3720.59N/00559.16W^000/000/A=000065 !W18!
|
||||||
|
FMT798890>OGFLYM,qAS,FLYMASTER:/155444h3720.59N/00559.16W^000/000/A=000039 !W29!
|
||||||
|
FMT924469>OGFLYM,qAS,FLYMASTER:/155447h3720.59N/00559.16W^000/000/A=000039 !W28!
|
||||||
|
FMT842374>OGFLYM,qAS,FLYMASTER:/155453h3720.60N/00559.17W^316/020/A=000055 !W07!
|
||||||
|
FMT003549>OGFLYM,qAS,FLYMASTER:/155455h3751.82N/00125.81W^248/012/A=001676 !W99!
|
|
@ -1,4 +1,4 @@
|
||||||
# The following beacons are example for INREACH APRS format
|
# The following beacons are example for Garmin inReach APRS format
|
||||||
# source: https://github.com/glidernet/ogn-aprs-protocol
|
# source: https://github.com/glidernet/ogn-aprs-protocol
|
||||||
#
|
#
|
||||||
OGN8A0749>OGINREACH,qAS,INREACH:/142700h0448.38N/07600.74W'000/000/A=004583 id300434060496190 inReac True
|
OGN8A0749>OGINREACH,qAS,INREACH:/142700h0448.38N/07600.74W'000/000/A=004583 id300434060496190 inReac True
|
Ładowanie…
Reference in New Issue