def bds_info(BDS, m): if BDS == "BDS10": info = [commb.ovc10(m)] elif BDS == "BDS17": info = ([i[-2:] for i in commb.cap17(m)]) elif BDS == "BDS20": info = [commb.cs20(m)] elif BDS == "BDS40": info = (commb.selalt40mcp(m), commb.selalt40fms(m), commb.p40baro(m)) elif BDS == "BDS44": info = (commb.wind44(m), commb.temp44(m), commb.p44(m), commb.hum44(m)) elif BDS == "BDS44REV": info = (commb.wind44(m, rev=True), commb.temp44(m, rev=True), commb.p44(m, rev=True), commb.hum44(m, rev=True)) elif BDS == "BDS50": info = (commb.roll50(m), commb.trk50(m), commb.gs50(m), commb.rtrk50(m), commb.tas50(m)) elif BDS == "BDS60": info = (commb.hdg60(m), commb.ias60(m), commb.mach60(m), commb.vr60baro(m), commb.vr60ins(m)) else: info = None return info
def test_bds50_functions(): assert bds.bds50.roll50("A000139381951536E024D4CCF6B5") == 2.1 assert bds.bds50.roll50("A0001691FFD263377FFCE02B2BF9") == -0.4 # signed value assert bds.bds50.trk50("A000139381951536E024D4CCF6B5") == 114.258 assert bds.bds50.gs50("A000139381951536E024D4CCF6B5") == 438 assert bds.bds50.rtrk50("A000139381951536E024D4CCF6B5") == 0.125 assert bds.bds50.tas50("A000139381951536E024D4CCF6B5") == 424 assert commb.roll50("A000139381951536E024D4CCF6B5") == 2.1 assert commb.roll50("A0001691FFD263377FFCE02B2BF9") == -0.4 # signed value assert commb.trk50("A000139381951536E024D4CCF6B5") == 114.258 assert commb.gs50("A000139381951536E024D4CCF6B5") == 438 assert commb.rtrk50("A000139381951536E024D4CCF6B5") == 0.125 assert commb.tas50("A000139381951536E024D4CCF6B5") == 424
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")
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")
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