diff --git a/pyModeS/decoder/adsb.py b/pyModeS/decoder/adsb.py index e74f6c2..1d65849 100644 --- a/pyModeS/decoder/adsb.py +++ b/pyModeS/decoder/adsb.py @@ -28,6 +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_state, emergency_squawk def df(msg): diff --git a/pyModeS/decoder/bds/bds61.py b/pyModeS/decoder/bds/bds61.py new file mode 100644 index 0000000..05dc649 --- /dev/null +++ b/pyModeS/decoder/bds/bds61.py @@ -0,0 +1,83 @@ +# ------------------------------------------ +# BDS 6,1 +# ADS-B TC=28 +# Aircraft Airborne status +# ------------------------------------------ + +from pyModeS import common + + +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: 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]) + + if subtype == 2: + raise RuntimeError("%s: Emergency message is ACAS-RA, not implemented") + + emergency_state = common.bin2int(mb[8:11]) + + if subtype == 1 and emergency_state == 1: + return True + else: + return False + + +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 + """ + + 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) + + msgbin = common.hex2bin(msg) + + # 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 64599ab..c6e6de0 100644 --- a/tests/test_adsb.py +++ b/tests/test_adsb.py @@ -80,6 +80,12 @@ def test_adsb_velocity(): assert adsb.altitude_diff("8D485020994409940838175B284F") == 550 +def test_adsb_emergency(): + assert not adsb.is_emergency("8DA2C1B6E112B600000000760759") + assert adsb.emergency_state("8DA2C1B6E112B600000000760759") == 0 + assert adsb.emergency_squawk("8DA2C1B6E112B600000000760759") == "6615" + + # def test_nic(): # assert adsb.nic('8D3C70A390AB11F55B8C57F65FE6') == 0 # assert adsb.nic('8DE1C9738A4A430B427D219C8225') == 1