diff --git a/pyModeS/decoder/allcall.py b/pyModeS/decoder/allcall.py index 6e296ca..5f352f4 100644 --- a/pyModeS/decoder/allcall.py +++ b/pyModeS/decoder/allcall.py @@ -1,5 +1,75 @@ """ -Decoding all call replies DF=11 +Decode all-call reply messages, with dowlink format 11 +""" -[To be implemented] -""" +from pyModeS import common + + +def _checkdf(func): + """Ensure downlink format is 11.""" + + def wrapper(msg): + df = common.df(msg) + if df != 11: + raise RuntimeError( + "Incorrect downlink format, expect 11, got {}".format(df) + ) + return func(msg) + + return wrapper + + +@_checkdf +def icao(msg): + """Decode transponder code (ICAO address). + + Args: + msg (str): 14 hexdigits string + Returns: + string: ICAO address + + """ + return common.icao(msg) + + +@_checkdf +def interrogator(msg): + """Decode interrogator identifier code. + + Args: + msg (str): 14 hexdigits string + Returns: + int: interrogator identifier code + + """ + # simply the CRC reminder + return common.crc(msg) + + +@_checkdf +def capability(msg): + """Decode transponder capability. + + Args: + msg (str): 14 hexdigits string + Returns: + int, str: transponder capability, description + + """ + msgbin = common.hex2bin(msg) + ca = common.bin2int(msgbin[5:8]) + + if ca == 0: + text = "level 1 transponder" + elif ca == 4: + text = "level 2 transponder, ability to set CA to 7, on ground" + elif ca == 5: + text = "level 2 transponder, ability to set CA to 7, airborne" + elif ca == 6: + text = "evel 2 transponder, ability to set CA to 7, either airborne or ground" + elif ca == 7: + text = "Downlink Request value is 0,or the Flight Status is 2, 3, 4 or 5, either airborne or on the ground" + else: + text = None + + return ca, text diff --git a/pyModeS/decoder/surv.py b/pyModeS/decoder/surv.py index 746f47f..ceec90c 100644 --- a/pyModeS/decoder/surv.py +++ b/pyModeS/decoder/surv.py @@ -1,5 +1,132 @@ """ -Warpper for short roll call surveillance replies DF=4/5 +Decode short roll call surveillance replies, with downlink format 4 or 5 +""" -[To be implemented] -""" +from pyModeS import common + + +def _checkdf(func): + """Ensure downlink format is 4 or 5.""" + + def wrapper(msg): + df = common.df(msg) + if df not in [4, 5]: + raise RuntimeError( + "Incorrect downlink format, expect 4 or 5, got {}".format(df) + ) + return func(msg) + + return wrapper + + +@_checkdf +def fs(msg): + """Decode flight status. + + Args: + msg (str): 14 hexdigits string + Returns: + int, str: flight status, description + + """ + msgbin = common.hex2bin(msg) + fs = common.bin2int(msgbin[5:8]) + text = None + + if fs == 0: + text = "no alert, no SPI, aircraft is airborne" + elif fs == 1: + text = "no alert, no SPI, aircraft is on-ground" + elif fs == 2: + text = "alert, no SPI, aircraft is airborne" + elif fs == 3: + text = "alert, no SPI, aircraft is on-ground" + elif fs == 4: + text = "alert, SPI, aircraft is airborne or on-ground" + elif fs == 5: + text = "no alert, SPI, aircraft is airborne or on-ground" + + return fs, text + + +@_checkdf +def dr(msg): + """Decode downlink request. + + Args: + msg (str): 14 hexdigits string + Returns: + int, str: downlink request, description + + """ + msgbin = common.hex2bin(msg) + dr = common.bin2int(msgbin[8:13]) + + text = None + + if dr == 0: + text = "no downlink request" + elif dr == 1: + text = "request to send Comm-B message" + elif dr == 4: + text = "Comm-B broadcast 1 available" + elif dr == 5: + text = "Comm-B broadcast 2 available" + elif dr >= 16: + text = "ELM downlink segments available: {}".format(dr - 15) + + return dr, text + + +@_checkdf +def um(msg): + """Decode utility message. + + Utility message contains interrogator identifier and reservation type. + + Args: + msg (str): 14 hexdigits string + Returns: + int, str: interrogator identifier code that triggered the reply, and + reservation type made by the interrogator + """ + msgbin = common.hex2bin(msg) + iis = common.bin2int(msgbin[13:17]) + ids = common.bin2int(msgbin[17:19]) + if ids == 0: + ids_text = None + if ids == 1: + ids_text = "Comm-B interrogator identifier code" + if ids == 2: + ids_text = "Comm-C interrogator identifier code" + if ids == 3: + ids_text = "Comm-D interrogator identifier code" + return iis, ids, ids_text + + +@_checkdf +def altitude(msg): + """Decode altitude. + + Args: + msg (String): 14 hexdigits string + + Returns: + int: altitude in ft + + """ + return common.altcode(msg) + + +@_checkdf +def identity(msg): + """Decode squawk code. + + Args: + msg (String): 14 hexdigits string + + Returns: + string: squawk code + + """ + return common.idcode(msg) diff --git a/tests/test_allcall.py b/tests/test_allcall.py new file mode 100644 index 0000000..e727d4b --- /dev/null +++ b/tests/test_allcall.py @@ -0,0 +1,13 @@ +from pyModeS import allcall + + +def test_icao(): + assert allcall.icao("5D484FDEA248F5") == "484FDE" + + +def test_interrogator(): + assert allcall.interrogator("5D484FDEA248F5") == 22 + + +def test_capability(): + assert allcall.capability("5D484FDEA248F5")[0] == 5 diff --git a/tests/test_surv.py b/tests/test_surv.py new file mode 100644 index 0000000..0286e27 --- /dev/null +++ b/tests/test_surv.py @@ -0,0 +1,22 @@ +from pyModeS import surv + + +def test_fs(): + assert surv.fs("2A00516D492B80")[0] == 2 + + +def test_dr(): + assert surv.dr("2A00516D492B80")[0] == 0 + + +def test_um(): + assert surv.um("200CBE4ED80137")[0] == 9 + assert surv.um("200CBE4ED80137")[1] == 1 + + +def test_identity(): + assert surv.identity("2A00516D492B80") == "0356" + + +def test_altitude(): + assert surv.altitude("20001718029FCD") == 36000