from typing import Any
from pyModeS import adsb, bds, commb, py_common
def decode(msg: str, common: Any = py_common) -> dict[str, Any]:
df = common.df(msg)
icao = common.icao(msg)
decoded = {"msg": msg, "icao": icao, "df": df}
if df == 17:
decoded["tc"] = tc = common.typecode(msg)
if tc is None:
return decoded
if 1 <= tc <= 4: callsign = adsb.callsign(msg)
decoded["bds"] = 10
decoded["callsign"] = callsign
if 5 <= tc <= 8: decoded["bds"] = "06"
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)
decoded["oddflag"] = "odd" if oe else "even"
decoded["cprlat"] = cprlat
decoded["cprlon"] = cprlon
decoded["speed"] = v[0]
decoded["track"] = v[1]
if 9 <= tc <= 18: decoded["bds"] = "05"
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
decoded["oddflag"] = "odd" if oe else "even"
decoded["cprlat"] = cprlat
decoded["cprlon"] = cprlon
decoded["altitude"] = alt
if tc == 19:
decoded["bds"] = "09"
velocity = adsb.velocity(msg)
if velocity is not None:
spd, trk, vr, t = velocity
types = {"GS": "Ground speed", "TAS": "True airspeed"}
decoded[types[t]] = spd
decoded["track"] = trk
decoded["vertical_rate"] = vr
if 20 <= tc <= 22: decoded["bds"] = "05"
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
decoded["oddflag"] = "odd" if oe else "even"
decoded["cprlat"] = cprlat
decoded["cprlon"] = cprlon
decoded["altitude"] = alt
if tc == 29: decoded["bds"] = "62"
subtype = common.bin2int((common.hex2bin(msg)[32:])[5:7])
tcas_operational = adsb.tcas_operational(msg)
types_29 = {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)
decoded["target_alt"] = alt
decoded["alt_source"] = alt_source
decoded["alt_reference"] = alt_ref
decoded["angle"] = angle
decoded["angle_type"] = angle_type
decoded["angle_source"] = angle_source
if vertical_mode is not None:
decoded["vnav_mode"] = (
vertical_horizontal_types[vertical_mode],
)
if horizontal_mode is not None:
decoded["lnav_mode"] = (
vertical_horizontal_types[horizontal_mode],
)
decoded["tcas"] = (
tcas_operational_types[tcas_operational]
if tcas_operational
else None,
)
decoded["tcas_type"] = tcas_ra_types[tcas_ra]
decoded["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)
decoded["selected_alt"] = alt
decoded["alt_source"] = alt_source
decoded["barometric_setting"] = baro
decoded["selected_hdg"] = hdg
if not (common.bin2int((common.hex2bin(msg)[32:])[46]) == 0):
decoded["autopilot"] = (
types_29[autopilot] if autopilot else None
)
decoded["vnav_mode"] = types_29[vnav] if vnav else None
decoded["alt_hold"] = (
types_29[alt_hold] if alt_hold else None,
)
decoded["app_mode"] = types_29[app] if app else None
decoded["tcas"] = (
tcas_operational_types[tcas_operational]
if tcas_operational
else None,
)
decoded["lnav_mode"] = types_29[lnav] if lnav else None
if df == 20:
decoded["altitude"] = common.altcode(msg)
if df == 21:
decoded["squawk"] = common.idcode(msg)
if df == 20 or df == 21:
decoded["bds"] = BDS = bds.infer(msg, mrar=True)
if BDS == "BDS20":
decoded["callsign"] = callsign = commb.cs20(msg)
if BDS == "BDS40":
decoded["selected_mcp"] = commb.selalt40mcp(msg)
decoded["selected_fms"] = commb.selalt40fms(msg)
decoded["selected_baro"] = commb.p40baro(msg)
if BDS == "BDS50":
decoded["Roll angle"] = commb.roll50(msg)
decoded["Track angle"] = commb.trk50(msg)
decoded["Track rate"] = commb.rtrk50(msg)
decoded["Ground speed"] = commb.gs50(msg)
decoded["True airspeed"] = commb.tas50(msg)
if BDS == "BDS60":
decoded["Megnatic Heading"] = commb.hdg60(msg)
decoded["Indicated airspeed"] = commb.ias60(msg)
decoded["Mach number"] = commb.mach60(msg)
decoded["Vertical rate (Baro)"] = commb.vr60baro(msg)
decoded["Vertical rate (INS)"] = commb.vr60ins(msg)
if BDS == "BDS44":
decoded["Wind speed"] = commb.wind44(msg)[0]
decoded["Wind direction"] = commb.wind44(msg)[1]
decoded["Temperature 1"] = commb.temp44(msg)[0]
decoded["Temperature 2"] = commb.temp44(msg)[1]
decoded["Pressure"] = commb.p44(msg)
decoded["Humidity"] = commb.hum44(msg)
decoded["Turbulence"] = commb.turb44(msg)
if BDS == "BDS45":
decoded["Turbulence"] = commb.turb45(msg)
decoded["Wind shear"] = commb.ws45(msg)
decoded["Microbust"] = commb.mb45(msg)
decoded["Icing"] = commb.ic45(msg)
decoded["Wake vortex"] = commb.wv45(msg)
decoded["Temperature"] = commb.temp45(msg)
decoded["Pressure"] = commb.p45(msg)
decoded["Radio height"] = commb.rh45(msg)
return decoded