Beispiel #1
0
def test_bds_infer():
    assert bds.infer("8D406B902015A678D4D220AA4BDA") == 'BDS08'
    assert bds.infer("8FC8200A3AB8F5F893096B000000") == 'BDS06'
    assert bds.infer("8D40058B58C901375147EFD09357") == 'BDS05'
    assert bds.infer("8D485020994409940838175B284F") == 'BDS09'

    assert bds.infer("A800178D10010080F50000D5893C") == 'BDS10'
    assert bds.infer("A0000638FA81C10000000081A92F") == 'BDS17'
    assert bds.infer("A0001838201584F23468207CDFA5") == 'BDS20'
    assert bds.infer("A0001839CA3800315800007448D9") == 'BDS40'
    assert bds.infer("A000139381951536E024D4CCF6B5") == 'BDS50'
    assert bds.infer("A00004128F39F91A7E27C46ADC21") == 'BDS60'
Beispiel #2
0
def commb_decode_all(df, n=None):
    import csv

    print("===== Decode Comm-B sample data (DF=%s)=====" % df)

    f = open("tests/data/sample_data_commb_df%s.csv" % df, "rt")

    for i, r in enumerate(csv.reader(f)):
        if n and i > n:
            break

        ts = r[0]
        m = r[2]

        df = common.df(m)
        icao = common.icao(m)
        BDS = bds.infer(m)
        code = common.altcode(m) if df == 20 else common.idcode(m)

        if not BDS:
            print(ts, m, icao, df, "%5s" % code, "UNKNOWN")
            continue

        if len(BDS.split(",")) > 1:
            print(ts, m, icao, df, "%5s" % code, end=" ")
            for i, _bds in enumerate(BDS.split(",")):
                if i == 0:
                    print(_bds, *bds_info(_bds, m))
                else:
                    print(" " * 55, _bds, *bds_info(_bds, m))

        else:
            print(ts, m, icao, df, "%5s" % code, BDS, *bds_info(BDS, m))
Beispiel #3
0
def tell(msg: str) -> None:
    from pyModeS import common, adsb, commb, bds

    def _print(label, value, unit=None):
        print("%20s: " % label, end="")
        print("%s " % value, end="")
        if unit:
            print(unit)
        else:
            print()

    df = common.df(msg)
    icao = common.icao(msg)

    _print("Message", msg)
    _print("ICAO address", icao)
    _print("Downlink Format", df)

    if df == 17:
        _print("Protocol", "Mode-S Extended Squitter (ADS-B)")

        tc = common.typecode(msg)
        if 1 <= tc <= 4:  # callsign
            callsign = adsb.callsign(msg)
            _print("Type", "Identitification and category")
            _print("Callsign:", callsign)

        if 5 <= tc <= 8:  # surface position
            _print("Type", "Surface position")
            oe = adsb.oe_flag(msg)
            msgbin = common.hex2bin(msg)
            cprlat = common.bin2int(msgbin[54:71]) / 131072.0
            cprlon = common.bin2int(msgbin[71:88]) / 131072.0
            v = adsb.surface_velocity(msg)
            _print("CPR format", "Odd" if oe else "Even")
            _print("CPR Latitude", cprlat)
            _print("CPR Longitude", cprlon)
            _print("Speed", v[0], "knots")
            _print("Track", v[1], "degrees")

        if 9 <= tc <= 18:  # airborne position
            _print("Type", "Airborne position (with barometric altitude)")
            alt = adsb.altitude(msg)
            oe = adsb.oe_flag(msg)
            msgbin = common.hex2bin(msg)
            cprlat = common.bin2int(msgbin[54:71]) / 131072.0
            cprlon = common.bin2int(msgbin[71:88]) / 131072.0
            _print("CPR format", "Odd" if oe else "Even")
            _print("CPR Latitude", cprlat)
            _print("CPR Longitude", cprlon)
            _print("Altitude", alt, "feet")

        if tc == 19:
            _print("Type", "Airborne velocity")
            spd, trk, vr, t = adsb.velocity(msg)
            types = {"GS": "Ground speed", "TAS": "True airspeed"}
            _print("Speed", spd, "knots")
            _print("Track", trk, "degrees")
            _print("Vertical rate", vr, "feet/minute")
            _print("Type", types[t])

        if 20 <= tc <= 22:  # airborne position
            _print("Type", "Airborne position (with GNSS altitude)")
            alt = adsb.altitude(msg)
            oe = adsb.oe_flag(msg)
            msgbin = common.hex2bin(msg)
            cprlat = common.bin2int(msgbin[54:71]) / 131072.0
            cprlon = common.bin2int(msgbin[71:88]) / 131072.0
            _print("CPR format", "Odd" if oe else "Even")
            _print("CPR Latitude", cprlat)
            _print("CPR Longitude", cprlon)
            _print("Altitude", alt, "feet")

    if df == 20:
        _print("Protocol", "Mode-S Comm-B altitude reply")
        _print("Altitude", common.altcode(msg), "feet")

    if df == 21:
        _print("Protocol", "Mode-S Comm-B identity reply")
        _print("Squawk code", common.idcode(msg))

    if df == 20 or df == 21:
        labels = {
            "BDS10": "Data link capability",
            "BDS17": "GICB capability",
            "BDS20": "Aircraft identification",
            "BDS30": "ACAS resolution",
            "BDS40": "Vertical intention report",
            "BDS50": "Track and turn report",
            "BDS60": "Heading and speed report",
            "BDS44": "Meteorological routine air report",
            "BDS45": "Meteorological hazard report",
            "EMPTY": "[No information available]",
        }

        BDS = bds.infer(msg, mrar=True)
        if BDS in labels.keys():
            _print("BDS", "%s (%s)" % (BDS, labels[BDS]))
        else:
            _print("BDS", BDS)

        if BDS == "BDS20":
            callsign = commb.cs20(msg)
            _print("Callsign", callsign)

        if BDS == "BDS40":
            _print("MCP target alt", commb.selalt40mcp(msg), "feet")
            _print("FMS Target alt", commb.selalt40fms(msg), "feet")
            _print("Pressure", commb.p40baro(msg), "millibar")

        if BDS == "BDS50":
            _print("Roll angle", commb.roll50(msg), "degrees")
            _print("Track angle", commb.trk50(msg), "degrees")
            _print("Track rate", commb.rtrk50(msg), "degree/second")
            _print("Ground speed", commb.gs50(msg), "knots")
            _print("True airspeed", commb.tas50(msg), "knots")

        if BDS == "BDS60":
            _print("Megnatic Heading", commb.hdg60(msg), "degrees")
            _print("Indicated airspeed", commb.ias60(msg), "knots")
            _print("Mach number", commb.mach60(msg))
            _print("Vertical rate (Baro)", commb.vr60baro(msg), "feet/minute")
            _print("Vertical rate (INS)", commb.vr60ins(msg), "feet/minute")

        if BDS == "BDS44":
            _print("Wind speed", commb.wind44(msg)[0], "knots")
            _print("Wind direction", commb.wind44(msg)[1], "degrees")
            _print("Temperature 1", commb.temp44(msg)[0], "Celsius")
            _print("Temperature 2", commb.temp44(msg)[1], "Celsius")
            _print("Pressure", commb.p44(msg), "hPa")
            _print("Humidity", commb.hum44(msg), "%")
            _print("Turbulence", commb.turb44(msg))

        if BDS == "BDS45":
            _print("Turbulence", commb.turb45(msg))
            _print("Wind shear", commb.ws45(msg))
            _print("Microbust", commb.mb45(msg))
            _print("Icing", commb.ic45(msg))
            _print("Wake vortex", commb.wv45(msg))
            _print("Temperature", commb.temp45(msg), "Celsius")
            _print("Pressure", commb.p45(msg), "hPa")
            _print("Radio height", commb.rh45(msg), "feet")
Beispiel #4
0
def tell(msg: str) -> None:
    from pyModeS import common, adsb, commb, bds

    def _print(label, value, unit=None):
        print("%20s: " % label, end="")
        print("%s " % value, end="")
        if unit:
            print(unit)
        else:
            print()

    df = common.df(msg)
    icao = common.icao(msg)

    _print("Message", msg)
    _print("ICAO address", icao)
    _print("Downlink Format", df)

    if df == 17:
        _print("Protocol", "Mode-S Extended Squitter (ADS-B)")

        tc = common.typecode(msg)
        if 1 <= tc <= 4:  # callsign
            callsign = adsb.callsign(msg)
            _print("Type", "Identification and category")
            _print("Callsign:", callsign)

        if 5 <= tc <= 8:  # surface position
            _print("Type", "Surface position")
            oe = adsb.oe_flag(msg)
            msgbin = common.hex2bin(msg)
            cprlat = common.bin2int(msgbin[54:71]) / 131072.0
            cprlon = common.bin2int(msgbin[71:88]) / 131072.0
            v = adsb.surface_velocity(msg)
            _print("CPR format", "Odd" if oe else "Even")
            _print("CPR Latitude", cprlat)
            _print("CPR Longitude", cprlon)
            _print("Speed", v[0], "knots")
            _print("Track", v[1], "degrees")

        if 9 <= tc <= 18:  # airborne position
            _print("Type", "Airborne position (with barometric altitude)")
            alt = adsb.altitude(msg)
            oe = adsb.oe_flag(msg)
            msgbin = common.hex2bin(msg)
            cprlat = common.bin2int(msgbin[54:71]) / 131072.0
            cprlon = common.bin2int(msgbin[71:88]) / 131072.0
            _print("CPR format", "Odd" if oe else "Even")
            _print("CPR Latitude", cprlat)
            _print("CPR Longitude", cprlon)
            _print("Altitude", alt, "feet")

        if tc == 19:
            _print("Type", "Airborne velocity")
            spd, trk, vr, t = adsb.velocity(msg)
            types = {"GS": "Ground speed", "TAS": "True airspeed"}
            _print("Speed", spd, "knots")
            _print("Track", trk, "degrees")
            _print("Vertical rate", vr, "feet/minute")
            _print("Type", types[t])

        if 20 <= tc <= 22:  # airborne position
            _print("Type", "Airborne position (with GNSS altitude)")
            alt = adsb.altitude(msg)
            oe = adsb.oe_flag(msg)
            msgbin = common.hex2bin(msg)
            cprlat = common.bin2int(msgbin[54:71]) / 131072.0
            cprlon = common.bin2int(msgbin[71:88]) / 131072.0
            _print("CPR format", "Odd" if oe else "Even")
            _print("CPR Latitude", cprlat)
            _print("CPR Longitude", cprlon)
            _print("Altitude", alt, "feet")

        if tc == 29:  # target state and status
            _print("Type", "Target State and Status")
            subtype = common.bin2int((common.hex2bin(msg)[32:])[5:7])
            _print("Subtype", subtype)
            tcas_operational = adsb.tcas_operational(msg)
            types = {0: "Not Engaged", 1: "Engaged"}
            tcas_operational_types = {0: "Not Operational", 1: "Operational"}
            if subtype == 0:
                emergency_types = {
                    0: "No emergency",
                    1: "General emergency",
                    2: "Lifeguard/medical emergency",
                    3: "Minimum fuel",
                    4: "No communications",
                    5: "Unlawful interference",
                    6: "Downed aircraft",
                    7: "Reserved"
                }
                vertical_horizontal_types = {
                    1: "Acquiring mode",
                    2: "Capturing/Maintaining mode"
                }
                tcas_ra_types = {0: "Not active", 1: "Active"}
                alt, alt_source, alt_ref = adsb.target_altitude(msg)
                angle, angle_type, angle_source = adsb.target_angle(msg)
                vertical_mode = adsb.vertical_mode(msg)
                horizontal_mode = adsb.horizontal_mode(msg)
                tcas_ra = adsb.tcas_ra(msg)
                emergency_status = adsb.emergency_status(msg)
                _print("Target altitude", alt, "feet")
                _print("Altitude source", alt_source)
                _print("Altitude reference", alt_ref)
                _print("Angle", angle, "°")
                _print("Angle Type", angle_type)
                _print("Angle Source", angle_source)
                _print("Vertical mode",
                       vertical_horizontal_types[vertical_mode])
                _print("Horizontal mode",
                       vertical_horizontal_types[horizontal_mode])
                _print("TCAS/ACAS", tcas_operational_types[tcas_operational])
                _print("TCAS/ACAS RA", tcas_ra_types[tcas_ra])
                _print("Emergency status", emergency_types[emergency_status])
            else:
                alt, alt_source = adsb.selected_altitude(msg)
                baro = adsb.baro_pressure_setting(msg)
                hdg = adsb.selected_heading(msg)
                autopilot = adsb.autopilot(msg)
                vnav = adsb.vnav_mode(msg)
                alt_hold = adsb.altitude_hold_mode(msg)
                app = adsb.approach_mode(msg)
                lnav = adsb.lnav_mode(msg)
                _print("Selected altitude", alt, "feet")
                _print("Altitude source", alt_source)
                _print("Barometric pressure setting", baro, "millibars")
                _print("Selected Heading", hdg, "°")
                if not (common.bin2int((common.hex2bin(msg)[32:])[46]) == 0):
                    _print("Autopilot", types[autopilot])
                    _print("VNAV mode", types[vnav])
                    _print("Altitude hold mode", types[alt_hold])
                    _print("Approach mode", types[app])
                    _print("TCAS/ACAS",
                           tcas_operational_types[tcas_operational])
                    _print("LNAV mode", types[lnav])

    if df == 20:
        _print("Protocol", "Mode-S Comm-B altitude reply")
        _print("Altitude", common.altcode(msg), "feet")

    if df == 21:
        _print("Protocol", "Mode-S Comm-B identity reply")
        _print("Squawk code", common.idcode(msg))

    if df == 20 or df == 21:
        labels = {
            "BDS10": "Data link capability",
            "BDS17": "GICB capability",
            "BDS20": "Aircraft identification",
            "BDS30": "ACAS resolution",
            "BDS40": "Vertical intention report",
            "BDS50": "Track and turn report",
            "BDS60": "Heading and speed report",
            "BDS44": "Meteorological routine air report",
            "BDS45": "Meteorological hazard report",
            "EMPTY": "[No information available]",
        }

        BDS = bds.infer(msg, mrar=True)
        if BDS in labels.keys():
            _print("BDS", "%s (%s)" % (BDS, labels[BDS]))
        else:
            _print("BDS", BDS)

        if BDS == "BDS20":
            callsign = commb.cs20(msg)
            _print("Callsign", callsign)

        if BDS == "BDS40":
            _print("MCP target alt", commb.selalt40mcp(msg), "feet")
            _print("FMS Target alt", commb.selalt40fms(msg), "feet")
            _print("Pressure", commb.p40baro(msg), "millibar")

        if BDS == "BDS50":
            _print("Roll angle", commb.roll50(msg), "degrees")
            _print("Track angle", commb.trk50(msg), "degrees")
            _print("Track rate", commb.rtrk50(msg), "degree/second")
            _print("Ground speed", commb.gs50(msg), "knots")
            _print("True airspeed", commb.tas50(msg), "knots")

        if BDS == "BDS60":
            _print("Megnatic Heading", commb.hdg60(msg), "degrees")
            _print("Indicated airspeed", commb.ias60(msg), "knots")
            _print("Mach number", commb.mach60(msg))
            _print("Vertical rate (Baro)", commb.vr60baro(msg), "feet/minute")
            _print("Vertical rate (INS)", commb.vr60ins(msg), "feet/minute")

        if BDS == "BDS44":
            _print("Wind speed", commb.wind44(msg)[0], "knots")
            _print("Wind direction", commb.wind44(msg)[1], "degrees")
            _print("Temperature 1", commb.temp44(msg)[0], "Celsius")
            _print("Temperature 2", commb.temp44(msg)[1], "Celsius")
            _print("Pressure", commb.p44(msg), "hPa")
            _print("Humidity", commb.hum44(msg), "%")
            _print("Turbulence", commb.turb44(msg))

        if BDS == "BDS45":
            _print("Turbulence", commb.turb45(msg))
            _print("Wind shear", commb.ws45(msg))
            _print("Microbust", commb.mb45(msg))
            _print("Icing", commb.ic45(msg))
            _print("Wake vortex", commb.wv45(msg))
            _print("Temperature", commb.temp45(msg), "Celsius")
            _print("Pressure", commb.p45(msg), "hPa")
            _print("Radio height", commb.rh45(msg), "feet")
Beispiel #5
0
def get_all(msg: str) -> dict:
    from pyModeS import common, adsb, commb, bds
    _dict = {}

    def push(key, data, unit=None):
        _dict[key] = data

    df = common.df(msg)
    icao = common.icao(msg)

    push("message", msg)
    push("icao", icao)
    push("downlink_format", df)

    if df == 17:
        push("protocol", "Mode-S Extended Squitter (ADS-B)")

        tc = common.typecode(msg)
        if 1 <= tc <= 4:  # callsign
            callsign = adsb.callsign(msg)
            push("type", "Identitification and category")
            push("callsign:", callsign)

        if 5 <= tc <= 8:  # surface position
            push("type", "Surface position")
            oe = adsb.oe_flag(msg)
            msgbin = common.hex2bin(msg)
            cprlat = common.bin2int(msgbin[54:71]) / 131072.0
            cprlon = common.bin2int(msgbin[71:88]) / 131072.0
            v = adsb.surface_velocity(msg)
            push("cpr_format", "Odd" if oe else "Even")
            push("cpr_latitude", cprlat)
            push("cpr_longitude", cprlon)
            push("speed", v[0] * 1.85200, "km")
            push("track", v[1], "degrees")

        if 9 <= tc <= 18:  # airborne position
            push("type", "Airborne position (with barometric altitude)")
            alt = adsb.altitude(msg)
            oe = adsb.oe_flag(msg)
            msgbin = common.hex2bin(msg)
            cprlat = common.bin2int(msgbin[54:71]) / 131072.0
            cprlon = common.bin2int(msgbin[71:88]) / 131072.0
            push("cpr_format", "Odd" if oe else "Even")
            push("cpr_latitude", cprlat)
            push("cpr_longitude", cprlon)
            push("altitude", alt, "feet")

        if tc == 19:
            push("type", "Airborne velocity")
            spd, trk, vr, t = adsb.velocity(msg)
            types = {"GS": "Ground speed", "TAS": "True airspeed"}
            push("speed", spd * 1.85200, "km")
            push("track", trk, "degrees")
            push("vertical rate", vr, "feet/minute")
            push("type", types[t])

        if 20 <= tc <= 22:  # airborne position
            push("type", "Airborne position (with GNSS altitude)")
            alt = adsb.altitude(msg)
            oe = adsb.oe_flag(msg)
            msgbin = common.hex2bin(msg)
            cprlat = common.bin2int(msgbin[54:71]) / 131072.0
            cprlon = common.bin2int(msgbin[71:88]) / 131072.0
            push("cpr_format", "Odd" if oe else "Even")
            push("cpr_latitude", cprlat)
            push("cpr_longitude", cprlon)
            push("altitude", alt, "feet")

        if tc == 29:  # target state and status
            push("type", "Target State and Status")
            subtype = common.bin2int((common.hex2bin(msg)[32:])[5:7])
            push("subtype", subtype)
            tcas_operational = adsb.tcas_operational(msg)
            types = {0: "Not Engaged", 1: "Engaged"}
            tcas_operational_types = {0: "Not Operational", 1: "Operational"}
            if subtype == 0:
                emergency_types = {
                    0: "No emergency",
                    1: "General emergency",
                    2: "Lifeguard/medical emergency",
                    3: "Minimum fuel",
                    4: "No communications",
                    5: "Unlawful interference",
                    6: "Downed aircraft",
                    7: "Reserved"
                }
                vertical_horizontal_types = {
                    1: "Acquiring mode",
                    2: "Capturing/Maintaining mode"
                }
                tcas_ra_types = {0: "Not active", 1: "Active"}
                altitude = adsb.target_altitude(msg)
                if altitude is not None:
                    alt, alt_source, alt_ref = altitude
                angle, angle_type, angle_source = adsb.target_angle(msg)
                vertical_mode = adsb.vertical_mode(msg)
                horizontal_mode = adsb.horizontal_mode(msg)
                tcas_ra = adsb.tcas_ra(msg)
                emergency_status = adsb.emergency_status(msg)
                push("target_altitude", alt, "feet")
                push("altitude_source", alt_source)
                push("altitude_reference", alt_ref)
                push("angle", angle, "°")
                push("angle Type", angle_type)
                push("angle Source", angle_source)
                push("vertical mode", vertical_horizontal_types[vertical_mode])
                push("horizontal mode", vertical_horizontal_types[horizontal_mode])
                push("TCAS/ACAS", tcas_operational_types[tcas_operational])
                push("TCAS/ACAS_RA", tcas_ra_types[tcas_ra])
                push("emergency_status", emergency_types[emergency_status])
            else:
                alt, alt_source = adsb.selected_altitude(msg)
                baro = adsb.baro_pressure_setting(msg)
                hdg = adsb.selected_heading(msg)
                autopilot = adsb.autopilot(msg)
                vnav = adsb.vnav_mode(msg)
                alt_hold = adsb.altitude_hold_mode(msg)
                app = adsb.approach_mode(msg)
                lnav = adsb.lnav_mode(msg)
                push("selected_altitude", alt, "feet")
                push("altitude_source", alt_source)
                push("barometric_pressure_setting", baro, "millibars")
                push("selected_Heading", hdg, "°")
                if not (common.bin2int((common.hex2bin(msg)[32:])[46]) == 0):
                    push("autopilot", types[autopilot])
                    push("VNAV_mode", types[vnav])
                    push("altitude_hold_mode", types[alt_hold])
                    push("approach_mode", types[app])
                    push("TCAS/ACAS", tcas_operational_types[tcas_operational])
                    push("LNAV_mode", types[lnav])

    if df == 20:
        push("protocol", "Mode-S Comm-B altitude reply")
        push("altitude", common.altcode(msg), "feet")

    if df == 21:
        push("protocol", "Mode-S Comm-B identity reply")
        push("squawk_code", common.idcode(msg))

    if df == 20 or df == 21:
        labels = {
            "BDS10": "Data link capability",
            "BDS17": "GICB capability",
            "BDS20": "Aircraft identification",
            "BDS30": "ACAS resolution",
            "BDS40": "Vertical intention report",
            "BDS50": "Track and turn report",
            "BDS60": "Heading and speed report",
            "BDS44": "Meteorological routine air report",
            "BDS45": "Meteorological hazard report",
            "EMPTY": "[No information available]",
        }

        BDS = bds.infer(msg, mrar=True)
        if BDS in labels.keys():
            push("BDS", "%s (%s)" % (BDS, labels[BDS]))
        else:
            push("BDS", BDS)

        if BDS == "BDS20":
            callsign = commb.cs20(msg)
            push("callsign", callsign)

        if BDS == "BDS40":
            push("MCP_target_alt", commb.selalt40mcp(msg), "feet")
            push("FMS_Target_alt", commb.selalt40fms(msg), "feet")
            push("pressure", commb.p40baro(msg), "millibar")

        if BDS == "BDS50":
            push("roll_angle", commb.roll50(msg), "degrees")
            push("track_angle", commb.trk50(msg), "degrees")
            push("track_rate", commb.rtrk50(msg), "degree/second")
            push("ground_speed", commb.gs50(msg)  * 1.85200, "km")
            push("true_airspeed", commb.tas50(msg)  * 1.85200, "km")

        if BDS == "BDS60":
            push("megnatic Heading", commb.hdg60(msg), "degrees")
            push("indicated airspeed", commb.ias60(msg)  * 1.85200, "km")
            push("mach number", commb.mach60(msg))
            push("vertical rate (Baro)", commb.vr60baro(msg), "feet/minute")
            push("vertical rate (INS)", commb.vr60ins(msg), "feet/minute")

        if BDS == "BDS44":
            push("wind_speed", commb.wind44(msg)[0]  * 1.85200, "km")
            push("wind_direction", commb.wind44(msg)[1], "degrees")
            push("temperature_1", commb.temp44(msg)[0], "Celsius")
            push("temperature_2", commb.temp44(msg)[1], "Celsius")
            push("pressure", commb.p44(msg), "hPa")
            push("humidity", commb.hum44(msg), "%")
            push("turbulence", commb.turb44(msg))

        if BDS == "BDS45":
            push("turbulence", commb.turb45(msg))
            push("wind_shear", commb.ws45(msg))
            push("microbust", commb.mb45(msg))
            push("icing", commb.ic45(msg))
            push("wake_vortex", commb.wv45(msg))
            push("temperature", commb.temp45(msg), "Celsius")
            push("pressure", commb.p45(msg), "hPa")
            push("radio_height", commb.rh45(msg), "feet")

    return _dict