Skip all keys where value is "None"

pull/83/head
Konstantin Gründger 2020-08-30 14:23:23 +02:00
rodzic b69e733df4
commit a610900548
7 zmienionych plików z 81 dodań i 59 usunięć

Wyświetl plik

@ -1,4 +1,7 @@
# CHANGELOG # CHANGELOG
## not released
- parser: Skip keys where value is "None"
## 0.9.8: - 2020-08-21 ## 0.9.8: - 2020-08-21
- parser: Changed InReach parser (fixes #73) - parser: Changed InReach parser (fixes #73)
- parser: separated incompatible ID into parser dependant ID (lt24: address -> lt24_id, skylines: address -> skylines_id, - parser: separated incompatible ID into parser dependant ID (lt24: address -> lt24_id, skylines: address -> skylines_id,

Wyświetl plik

@ -12,24 +12,20 @@ class FlarmParser(BaseParser):
def parse_position(self, aprs_comment): def parse_position(self, aprs_comment):
match = self.position_pattern.match(aprs_comment) match = self.position_pattern.match(aprs_comment)
def if_present(arg, func): return {k: v for (k, v) in
result = match.group(arg) {'address_type': int(match.group('details'), 16) & 0b00000011 if match.group('details') else None,
return (func(result)) if result else None 'aircraft_type': (int(match.group('details'), 16) & 0b01111100) >> 2 if match.group('details') else None,
'stealth': (int(match.group('details'), 16) & 0b10000000) >> 7 == 1 if match.group('details') else None,
return {'address_type': if_present('details', lambda x: int(x, 16) & 0b00000011), 'address': match.group('address') or None,
'aircraft_type': if_present('details', lambda x: (int(x, 16) & 0b01111100) >> 2), 'climb_rate': int(match.group('climb_rate')) * FPM_TO_MS if match.group('climb_rate') else None,
'stealth': if_present('details', lambda x: (int(x, 16) & 0b10000000) >> 7 == 1), 'turn_rate': float(match.group('turn_rate')) * HPM_TO_DEGS if match.group('turn_rate') else None,
'address': if_present('address', lambda x: x), 'signal_quality': float(match.group('signal_quality')) if match.group('signal_quality') else None,
'climb_rate': if_present('climb_rate', lambda x: int(x) * FPM_TO_MS), 'error_count': int(match.group('error_count')) if match.group('error_count') else None,
'turn_rate': if_present('turn_rate', lambda x: float(x) * HPM_TO_DEGS), 'frequency_offset': float(match.group('frequency_offset')) if match.group('frequency_offset') else None,
'signal_quality': if_present('signal_quality', float), 'gps_quality': {
'error_count': if_present('error_count', int),
'frequency_offset': if_present('frequency_offset', float),
'gps_quality': if_present('gps_quality', lambda _x: {
'horizontal': int(match.group('gps_quality_horizontal')), 'horizontal': int(match.group('gps_quality_horizontal')),
'vertical': int(match.group('gps_quality_vertical'))}), 'vertical': int(match.group('gps_quality_vertical'))} if match.group('gps_quality') else None,
'software_version': if_present('software_version', float), 'software_version': float(match.group('software_version')) if match.group('software_version') else None,
'hardware_version': if_present('hardware_version', lambda x: int(x, 16)), 'hardware_version': int(match.group('hardware_version'), 16) if match.group('hardware_version') else None,
'real_address': if_present('real_address', lambda x: x), 'real_address': match.group('real_address') or None,
'signal_power': if_present('signal_power', float), 'signal_power': float(match.group('signal_power')) if match.group('signal_power') else None}.items() if v is not None}
}

Wyświetl plik

@ -30,7 +30,8 @@ class OgnParser(BaseParser):
def parse_aircraft_beacon(self, aprs_comment): def parse_aircraft_beacon(self, aprs_comment):
ab_match = self.aircraft_pattern.match(aprs_comment) ab_match = self.aircraft_pattern.match(aprs_comment)
if ab_match: if ab_match:
return {'address_type': int(ab_match.group('details'), 16) & 0b00000011, return {k: v for (k, v) in
{'address_type': int(ab_match.group('details'), 16) & 0b00000011,
'aircraft_type': (int(ab_match.group('details'), 16) & 0b01111100) >> 2, 'aircraft_type': (int(ab_match.group('details'), 16) & 0b01111100) >> 2,
'stealth': (int(ab_match.group('details'), 16) & 0b10000000) >> 7 == 1, 'stealth': (int(ab_match.group('details'), 16) & 0b10000000) >> 7 == 1,
'address': ab_match.group('address'), 'address': ab_match.group('address'),
@ -46,14 +47,15 @@ class OgnParser(BaseParser):
'hardware_version': int(ab_match.group('flarm_hardware_version'), 16) if ab_match.group('flarm_hardware_version') else None, 'hardware_version': int(ab_match.group('flarm_hardware_version'), 16) if ab_match.group('flarm_hardware_version') else None,
'real_address': ab_match.group('flarm_id') if ab_match.group('flarm_id') else None, 'real_address': ab_match.group('flarm_id') if ab_match.group('flarm_id') else None,
'signal_power': float(ab_match.group('signal_power')) if ab_match.group('signal_power') else None, 'signal_power': float(ab_match.group('signal_power')) if ab_match.group('signal_power') else None,
'proximity': [hear[4:] for hear in ab_match.group('proximity').split(" ")] if ab_match.group('proximity') else None} 'proximity': [hear[4:] for hear in ab_match.group('proximity').split(" ")] if ab_match.group('proximity') else None}.items() if v is not None}
else: else:
return None return None
def parse_receiver_beacon(self, aprs_comment): def parse_receiver_beacon(self, aprs_comment):
rb_match = self.receiver_pattern.match(aprs_comment) rb_match = self.receiver_pattern.match(aprs_comment)
if rb_match: if rb_match:
return {'version': rb_match.group('version'), return {k: v for (k, v) in
{'version': rb_match.group('version'),
'platform': rb_match.group('platform'), 'platform': rb_match.group('platform'),
'cpu_load': float(rb_match.group('cpu_load')), 'cpu_load': float(rb_match.group('cpu_load')),
'free_ram': float(rb_match.group('ram_free')), 'free_ram': float(rb_match.group('ram_free')),
@ -72,6 +74,6 @@ class OgnParser(BaseParser):
'senders_messages': float(rb_match.group('senders_messages')) if rb_match.group('senders_messages') else None, 'senders_messages': float(rb_match.group('senders_messages')) if rb_match.group('senders_messages') else None,
'good_senders_signal': float(rb_match.group('good_senders_signal_quality')) if rb_match.group('good_senders_signal_quality') else None, 'good_senders_signal': float(rb_match.group('good_senders_signal_quality')) if rb_match.group('good_senders_signal_quality') else None,
'good_senders': float(rb_match.group('good_senders')) if rb_match.group('good_senders') else None, 'good_senders': float(rb_match.group('good_senders')) if rb_match.group('good_senders') else None,
'good_and_bad_senders': float(rb_match.group('good_and_bad_senders')) if rb_match.group('good_and_bad_senders') else None} 'good_and_bad_senders': float(rb_match.group('good_and_bad_senders')) if rb_match.group('good_and_bad_senders') else None}.items() if v is not None}
else: else:
return None return None

Wyświetl plik

@ -178,7 +178,7 @@ PATTERN_RECEIVER_BEACON = re.compile(r"""
\s)? \s)?
CPU:(?P<cpu_load>[\d.]+)\s CPU:(?P<cpu_load>[\d.]+)\s
RAM:(?P<ram_free>[\d.]+)/(?P<ram_total>[\d.]+)MB\s RAM:(?P<ram_free>[\d.]+)/(?P<ram_total>[\d.]+)MB\s
NTP:(?P<ntp_offset>[\d.]+)ms/(?P<ntp_correction>[+-][\d.]+)ppm\s NTP:(?P<ntp_offset>[\d.]+)ms/(?P<ntp_correction>[+-][\d.]+)ppm\s?
(?:(?P<voltage>[\d.]+)V\s)? (?:(?P<voltage>[\d.]+)V\s)?
(?:(?P<amperage>[\d.]+)A\s)? (?:(?P<amperage>[\d.]+)A\s)?
(?:(?P<cpu_temperature>[+-][\d.]+)C\s*)? (?:(?P<cpu_temperature>[+-][\d.]+)C\s*)?

Wyświetl plik

@ -22,6 +22,13 @@ class TestStringMethods(unittest.TestCase):
self.assertEqual(message['hardware_version'], 67) self.assertEqual(message['hardware_version'], 67)
self.assertEqual(message['real_address'], "DF0267") self.assertEqual(message['real_address'], "DF0267")
def test_position_comment_relevant_keys_only(self):
# return only keys where we got informations
message = FlarmParser().parse_position("id21A8CBA8")
self.assertIsNotNone(message)
self.assertEqual(sorted(message.keys()), sorted(['address_type', 'aircraft_type', 'stealth', 'address']))
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

Wyświetl plik

@ -58,6 +58,13 @@ class TestStringMethods(unittest.TestCase):
self.assertIsNotNone(message_triple) self.assertIsNotNone(message_triple)
self.assertIsNotNone(message_single) self.assertIsNotNone(message_single)
def test_relevant_keys_only(self):
# return only keys where we got informations
message = OgnParser().parse_aircraft_beacon("id093D0930")
self.assertIsNotNone(message)
self.assertEqual(sorted(message.keys()), sorted(['address_type', 'aircraft_type', 'stealth', 'address']))
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

Wyświetl plik

@ -42,6 +42,13 @@ class TestStringMethods(unittest.TestCase):
self.assertEqual(message['good_senders'], 68) self.assertEqual(message['good_senders'], 68)
self.assertEqual(message['good_and_bad_senders'], 135) self.assertEqual(message['good_and_bad_senders'], 135)
def test_relevant_keys_only(self):
# return only keys where we got informations
message = OgnParser().parse_receiver_beacon("v0.2.5.ARM CPU:0.4 RAM:638.0/970.5MB NTP:0.2ms/-1.1ppm")
self.assertIsNotNone(message)
self.assertEqual(sorted(message.keys()), sorted(['version', 'platform', 'cpu_load', 'free_ram', 'total_ram', 'ntp_error', 'rt_crystal_correction']))
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()