From 0c5539be3a22c28c7ea290bfecc48e11a4cf0eb4 Mon Sep 17 00:00:00 2001 From: Junzi Sun Date: Sat, 23 May 2020 21:07:23 +0200 Subject: [PATCH] update BDS61 decoder --- pyModeS/decoder/adsb.py | 2 +- pyModeS/decoder/bds/bds61.py | 113 +++++++++++++++-------------------- tests/test_adsb.py | 5 +- 3 files changed, 53 insertions(+), 67 deletions(-) diff --git a/pyModeS/decoder/adsb.py b/pyModeS/decoder/adsb.py index d9ed7fd..1d65849 100644 --- a/pyModeS/decoder/adsb.py +++ b/pyModeS/decoder/adsb.py @@ -28,7 +28,7 @@ from pyModeS.decoder.bds.bds06 import ( ) from pyModeS.decoder.bds.bds08 import category, callsign from pyModeS.decoder.bds.bds09 import airborne_velocity, altitude_diff -from pyModeS.decoder.bds.bds61 import is_emergency, emergency, emergency_squawk +from pyModeS.decoder.bds.bds61 import is_emergency, emergency_state, emergency_squawk def df(msg): diff --git a/pyModeS/decoder/bds/bds61.py b/pyModeS/decoder/bds/bds61.py index 495382e..05dc649 100644 --- a/pyModeS/decoder/bds/bds61.py +++ b/pyModeS/decoder/bds/bds61.py @@ -4,95 +4,80 @@ # Aircraft Airborne status # ------------------------------------------ -from __future__ import absolute_import, print_function, division - from pyModeS import common -def is_emergency(msg): - """ - Check if the aircraft is reporting an emergency +def is_emergency(msg: str) -> bool: + """Check if the aircraft is reporting an emergency. + Non-emergencies are either a subtype of zero (no information) or subtype of one and a value of zero (no emergency). Subtype = 2 indicates an ACAS RA broadcast, look in BDS 3,0 - :param msg: + + :param msg: 28 bytes hexadecimal message string :return: if the aircraft has declared an emergency """ if common.typecode(msg) != 28: raise RuntimeError("%s: Not an airborne status message, expecting TC=28" % msg) mb = common.hex2bin(msg)[32:] - subtype = common.bin2int(mb[5:8]) - emergency_state = common.bin2int(mb[8:11]) if subtype == 2: raise RuntimeError("%s: Emergency message is ACAS-RA, not implemented") - if subtype == 0: - return False - elif subtype == 1 and emergency_state == 0: - return False - else: + emergency_state = common.bin2int(mb[8:11]) + + if subtype == 1 and emergency_state == 1: return True - - -def emergency(msg): - """ - Return the aircraft emergency - - ===== ======= - Value Meaning - ===== ======= - 1 General emergency - 2 Lifeguard/Medical - 3 Minimum fuel - 4 No communications - 5 Unlawful communications - 6 Reserved - 7 Reserved - :param msg: - :return: If the aircraft has declared an emergency, the type - """ - if not is_emergency(msg): - raise RuntimeError("%s: Aircraft not declared an emergency" % msg) else: - mb = common.hex2bin(msg)[32:] - - subtype = common.bin2int(mb[5:8]) - emergency_state = common.bin2int(mb[8:11]) - - return emergency_state + return False -def emergency_squawk(msg): +def emergency_state(msg: str) -> int: + """Decode aircraft emergency state. + + Value Meaning + ----- ----------------------- + 0 No emergency + 1 General emergency + 2 Lifeguard/Medical + 3 Minimum fuel + 4 No communications + 5 Unlawful communications + 6-7 Reserved + + :param msg: 28 bytes hexadecimal message string + :return: emergency state """ - Squawk code of the transmitting aircraft - Emergency value 1 will be squawk 7700 - Emergency value 4 will be squawk 7600 - Emergency value 5 will be squawk 7500 - :param msg: + + mb = common.hex2bin(msg)[32:] + subtype = common.bin2int(mb[5:8]) + + if subtype == 2: + raise RuntimeError("%s: Emergency message is ACAS-RA, not implemented") + + emergency_state = common.bin2int(mb[8:11]) + return emergency_state + + +def emergency_squawk(msg: str) -> str: + """Decode squawk code. + + Emergency value 1: squawk 7700. + Emergency value 4: squawk 7600. + Emergency value 5: squawk 7500. + + :param msg: 28 bytes hexadecimal message string :return: aircraft squawk code """ if common.typecode(msg) != 28: raise RuntimeError("%s: Not an airborne status message, expecting TC=28" % msg) - mb = common.hex2bin(msg)[32:] - C1 = mb[11] - A1 = mb[12] - C2 = mb[13] - A2 = mb[14] - C4 = mb[15] - A4 = mb[16] - B1 = mb[17] - D1 = mb[18] - B2 = mb[19] - D2 = mb[20] - B4 = mb[21] - D4 = mb[22] + msgbin = common.hex2bin(msg) - byte1 = int(A4 + A2 + A1, 2) - byte2 = int(B4 + B2 + B1, 2) - byte3 = int(C4 + C2 + C1, 2) - byte4 = int(D4 + D2 + D1, 2) - return str(byte1) + str(byte2) + str(byte3) + str(byte4) + # construct the 13 bits Mode A ID code + idcode = msgbin[43:49] + "0" + msgbin[49:55] + + squawk = common.squawk(idcode) + return squawk diff --git a/tests/test_adsb.py b/tests/test_adsb.py index 45db5fa..c6e6de0 100644 --- a/tests/test_adsb.py +++ b/tests/test_adsb.py @@ -81,8 +81,9 @@ def test_adsb_velocity(): def test_adsb_emergency(): - assert not adsb.is_emergency('8DA2C1B6E112B600000000760759') - assert adsb.emergency_squawk('8DA2C1B6E112B600000000760759') == '6615' + assert not adsb.is_emergency("8DA2C1B6E112B600000000760759") + assert adsb.emergency_state("8DA2C1B6E112B600000000760759") == 0 + assert adsb.emergency_squawk("8DA2C1B6E112B600000000760759") == "6615" # def test_nic():