from typing import Any from pyModeS import adsb, bds, commb, py_common # type: ignore def decode(msg: str, common: Any = py_common) -> dict[str, Any]: """rs1090.decode coded in pyModeS This is a rough equivalement of the rs1090 decode function (with few fields left undecoded). Let's say it's not a big deal. There **must** be some imprecisions, but that's enough for benchmarking. """ 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 callsign = adsb.callsign(msg) decoded["bds"] = 10 decoded["callsign"] = callsign if 5 <= tc <= 8: # surface position 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: # airborne position 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: # airborne position 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: # target state and status 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