from __future__ import annotations
from typing import Literal, TypedDict, Union, overload
from typing_extensions import (
NotRequired, TypeGuard, )
class BDS05(TypedDict):
bds: Literal["05"]
NUCp: int
NICb: int
altitude: int
source: str
parity: Literal["odd", "even"]
lat_cpr: int
lon_cpr: int
latitude: NotRequired[float]
longitude: NotRequired[float]
class BDS10(TypedDict):
bds: Literal["10"]
config: bool
ovc: bool
acas: bool
subnet: int
level5: bool
mode_s: bool
identification: bool
squitter: bool
sic: bool
gicb: bool
acas_hybrid: bool
acas_ra: bool
dte: int
class BDS17(TypedDict):
bds: Literal["17"]
bds05: NotRequired[Literal[True]]
bds06: NotRequired[Literal[True]]
bds07: NotRequired[Literal[True]]
bds08: NotRequired[Literal[True]]
bds09: NotRequired[Literal[True]]
bds0a: NotRequired[Literal[True]]
bds20: Literal[True]
bds40: NotRequired[Literal[True]]
bds41: NotRequired[Literal[True]]
bds42: NotRequired[Literal[True]]
bds43: NotRequired[Literal[True]]
bds44: NotRequired[Literal[True]]
bds45: NotRequired[Literal[True]]
bds48: NotRequired[Literal[True]]
bds50: NotRequired[Literal[True]]
bds51: NotRequired[Literal[True]]
bds52: NotRequired[Literal[True]]
bds53: NotRequired[Literal[True]]
bds54: NotRequired[Literal[True]]
bds55: NotRequired[Literal[True]]
bds56: NotRequired[Literal[True]]
bds5f: NotRequired[Literal[True]]
bds60: NotRequired[Literal[True]]
class BDS20(TypedDict):
bds: Literal["20"]
callsign: str
icao24: str
class BDS21(TypedDict):
bds: Literal["21"]
registration: None | str
airline: None | str
class BDS30(TypedDict):
bds: Literal["30"]
issued_ra: bool
corrective: NotRequired[bool]
downward_sense: NotRequired[bool]
increased_rate: NotRequired[bool]
sense_reversal: NotRequired[bool]
altitude_crossing: NotRequired[bool]
positive: NotRequired[bool]
no_below: NotRequired[bool]
no_above: NotRequired[bool]
no_left: NotRequired[bool]
no_right: NotRequired[bool]
terminated: NotRequired[bool]
multiple: NotRequired[bool]
threat_identity: NotRequired[str]
threat_altitude: NotRequired[int]
threat_range: NotRequired[float]
threat_bearing: NotRequired[int]
class BDS40(TypedDict):
bds: Literal["40"]
selected_mcp: NotRequired[int]
selected_fms: NotRequired[int]
barometric_setting: NotRequired[float]
target_source: Literal[
"AircraftAltitude", "FcpMcuSelectedAltitude", "FmsSelectedAltitude"
]
class BDS44(TypedDict):
bds: Literal["44"]
issued_ra: bool
terminated: bool
multiple: bool
wind_speed: None | int
wind_direction: None | float
temperature: float
pressure: None | int
turbulence: Literal[None, "Nil", "Light", "Moderate", "Severe"]
humidity: None | float
class BDS45(TypedDict):
bds: Literal["45"]
turbulence: Literal[None, "Nil", "Light", "Moderate", "Severe"]
wind_shear: Literal[None, "Nil", "Light", "Moderate", "Severe"]
icing: Literal[None, "Nil", "Light", "Moderate", "Severe"]
wake_vortex: Literal[None, "Nil", "Light", "Moderate", "Severe"]
static_temperature: float
static_pressure: int
radio_hein: None | int
class BDS50(TypedDict):
bds: Literal["50"]
roll: None | float
track: None | float
groundspeed: None | int
track_rate: None | float
TAS: None | int
class BDS60(TypedDict):
bds: Literal["60"]
heading: NotRequired[float]
IAS: NotRequired[int]
Mach: NotRequired[float]
vrate_barometric: NotRequired[int]
vrate_inertial: NotRequired[int]
class DF0(TypedDict):
timestamp: float
df: Literal["0"]
altitude: int
icao24: str
class DF4(TypedDict):
timestamp: float
df: Literal["4"]
altitude: int
icao24: str
class DF5(TypedDict):
timestamp: float
df: Literal["5"]
squawk: str
icao24: str
class DF11(TypedDict):
timestamp: float
df: Literal["11"]
capability: str
icao24: str
class DF16(TypedDict):
timestamp: float
df: Literal["16"]
vs: int
sl: int
ri: int
altitude: int
icao24: str
class DF17_BDS05(TypedDict):
timestamp: float
df: Literal["17"]
icao24: str
bds: Literal["05"]
NUCp: int
NICb: int
altitude: int
source: str
parity: Literal["odd", "even"]
lat_cpr: int
lon_cpr: int
latitude: NotRequired[float]
longitude: NotRequired[float]
class DF17_BDS06(TypedDict):
timestamp: float
df: Literal["17"]
icao24: str
bds: Literal["06"]
NUCp: int
groundspeed: None | float
track: None | float
parity: Literal["odd", "even"]
lat_cpr: int
lon_cpr: int
latitude: NotRequired[float]
longitude: NotRequired[float]
class DF17_BDS08(TypedDict):
timestamp: float
df: Literal["17"]
icao24: str
bds: Literal["08"]
wake_vortex: Literal[
"n/a",
"Surface emergency vehicle",
"Surface service vehicle",
"Obstruction",
"Glider",
"Lighter than air",
"Parachutist",
"Ultralight",
"UAM",
"Space",
"<7000kg",
"34,000kg",
"<136,000kg",
"High vortex",
"Heavy",
"High performance",
"Rotorcraft",
]
callsign: str
class DF17_BDS09(TypedDict):
timestamp: float
df: Literal["17"]
icao24: str
bds: Literal["09"]
NACv: int
groundspeed: NotRequired[float]
TAS: NotRequired[float]
IAS: NotRequired[float]
track: NotRequired[float]
heading: NotRequired[float]
vrate_src: str
vertical_rate: int
geo_minus_baro: None | int
class DF17_BDS61(TypedDict):
timestamp: float
df: str
icao24: str
bds: Literal["61"]
subtype: Literal["emergency_priority", "acas_ra"]
emergency_state: Literal[
"none",
"general",
"medical",
"minimum_fuel",
"no_communication",
"unlawful_interference",
"downed_aircraft",
"reserved",
]
squawk: str
class DF17_BDS62(TypedDict):
timestamp: float
df: Literal["17"]
icao24: str
bds: Literal["62"]
source: str
selected_altitude: int
barometric_setting: float
selected_heading: NotRequired[float]
NACp: int
autopilot: NotRequired[bool]
vnav_mode: NotRequired[bool]
alt_hold: NotRequired[bool]
approach_mode: NotRequired[bool]
tcas_operational: bool
lnav_mode: NotRequired[bool]
class DF17_BDS65(TypedDict):
timestamp: float
df: Literal["17"]
icao24: str
bds: Literal["65"]
version: Literal["1", "2"]
NICa: int
NICs: NotRequired[int]
NACp: int
GVA: NotRequired[int]
BAI: int
BAQ: NotRequired[int]
TAH: NotRequired[int]
HRD: Literal[0, 1]
SIL: int
SILs: int
class DF17_Unknown(TypedDict):
timestamp: float
df: Literal["17"]
icao24: str
bds: Literal["?"]
class DF18_BDS06(TypedDict):
timestamp: float
df: Literal["18"]
tisb: Literal[
"ADSB_ES_NT",
"ADSB_ES_NT_ALT",
"TISB_FINE",
"TISB_COARSE",
"TISB_MANAGE",
"TISB_ADSB_RELAY",
"TISB_ADSB",
"Reserved",
]
icao24: str
bds: Literal["06"]
NUCp: int
groundspeed: None | float
track: None | float
parity: Literal["odd", "even"]
lat_cpr: int
lon_cpr: int
latitude: NotRequired[float]
longitude: NotRequired[float]
class DF18_BDS08(TypedDict):
timestamp: float
df: Literal["18"]
tisb: Literal[
"ADSB_ES_NT",
"ADSB_ES_NT_ALT",
"TISB_FINE",
"TISB_COARSE",
"TISB_MANAGE",
"TISB_ADSB_RELAY",
"TISB_ADSB",
"Reserved",
]
icao24: str
bds: Literal["08"]
wake_vortex: Literal[
"n/a",
"Surface emergency vehicle",
"Surface service vehicle",
"Obstruction",
"Glider",
"Lighter than air",
"Parachutist",
"Ultralight",
"UAM",
"Space",
"<7000kg",
"34,000kg",
"<136,000kg",
"High vortex",
"Heavy",
"High performance",
"Rotorcraft",
]
callsign: str
class DF18_BDS65(TypedDict):
timestamp: float
df: Literal["18"]
tisb: Literal[
"ADSB_ES_NT",
"ADSB_ES_NT_ALT",
"TISB_FINE",
"TISB_COARSE",
"TISB_MANAGE",
"TISB_ADSB_RELAY",
"TISB_ADSB",
"Reserved",
]
icao24: str
bds: Literal["65"]
version: Literal["1", "2"]
NICa: int
NICs: NotRequired[int]
NACp: int
GVA: NotRequired[int]
BAI: int
BAQ: NotRequired[int]
TAH: NotRequired[int]
HRD: Literal[0, 1]
SIL: int
SILs: int
class DF18_Unknown(TypedDict):
timestamp: float
df: Literal["18"]
tisb: Literal[
"ADSB_ES_NT",
"ADSB_ES_NT_ALT",
"TISB_FINE",
"TISB_COARSE",
"TISB_MANAGE",
"TISB_ADSB_RELAY",
"TISB_ADSB",
"Reserved",
]
icao24: str
bds: Literal["?"]
class DF20(TypedDict):
timestamp: float
df: Literal["20"]
altitude: int
icao24: str
bds05: None | BDS05
bds10: None | BDS10
bds17: None | BDS17
bds20: None | BDS20
bds21: None | BDS21
bds30: None | BDS30
bds40: None | BDS40
bds44: None | BDS44
bds45: None | BDS45
bds50: None | BDS50
bds60: None | BDS60
class DF21(TypedDict):
timestamp: float
df: Literal["21"]
squawk: str
icao24: str
bds10: None | BDS10
bds17: None | BDS17
bds20: None | BDS20
bds21: None | BDS21
bds30: None | BDS30
bds40: None | BDS40
bds44: None | BDS44
bds45: None | BDS45
bds50: None | BDS50
bds60: None | BDS60
DF17 = Union[
DF17_Unknown,
DF17_BDS05,
DF17_BDS06,
DF17_BDS08,
DF17_BDS09,
DF17_BDS61,
DF17_BDS62,
DF17_BDS65,
]
DF18 = Union[
DF18_Unknown,
DF18_BDS06,
DF18_BDS08,
DF18_BDS65,
]
Message = Union[DF0, DF4, DF5, DF11, DF16, DF17, DF18, DF20, DF21]
def is_df0(message: Message) -> TypeGuard[DF0]:
return message["df"] == "0"
def is_df4(message: Message) -> TypeGuard[DF4]:
return message["df"] == "4"
def is_df5(message: Message) -> TypeGuard[DF5]:
return message["df"] == "5"
def is_df11(message: Message) -> TypeGuard[DF11]:
return message["df"] == "11"
def is_df16(message: Message) -> TypeGuard[DF16]:
return message["df"] == "16"
def is_df17(message: Message) -> TypeGuard[DF17]:
return message["df"] == "17"
def is_df18(message: Message) -> TypeGuard[DF18]:
return message["df"] == "18"
def is_df20(message: Message) -> TypeGuard[DF20]:
return message["df"] == "20"
def is_df21(message: Message) -> TypeGuard[DF21]:
return message["df"] == "21"
def is_bds05(message: DF17) -> TypeGuard[DF17_BDS05]:
return message.get("bds", None) == "05" or "bds05" in message
@overload
def is_bds06(message: DF17) -> TypeGuard[DF17_BDS06]: ...
@overload
def is_bds06(message: DF18) -> TypeGuard[DF18_BDS06]: ...
def is_bds06(message: DF17 | DF18) -> TypeGuard[DF17_BDS06 | DF18_BDS06]:
return message.get("bds", None) == "06" or "bds06" in message
@overload
def is_bds08(message: DF17) -> TypeGuard[DF17_BDS08]: ...
@overload
def is_bds08(message: DF18) -> TypeGuard[DF18_BDS08]: ...
def is_bds08(message: DF17 | DF18) -> TypeGuard[DF17_BDS08 | DF18_BDS08]:
return message.get("bds", None) == "08" or "bds08" in message
def is_bds09(message: DF17) -> TypeGuard[DF17_BDS09]:
return message.get("bds", None) == "09" or "bds09" in message
def is_bds10(message: DF20 | DF21) -> bool:
return message.get("bds", None) == "10" or "bds10" in message
def is_bds17(message: DF20 | DF21) -> bool:
return message.get("bds", None) == "17" or "bds17" in message
def is_bds20(message: DF20 | DF21) -> bool:
return message.get("bds", None) == "20" or "bds20" in message
def is_bds30(message: DF20 | DF21) -> bool:
return message.get("bds", None) == "30" or "bds30" in message
def is_bds40(message: DF20 | DF21) -> bool:
return message.get("bds", None) == "40" or "bds40" in message
def is_bds44(message: DF20 | DF21) -> bool:
return message.get("bds", None) == "44" or "bds44" in message
def is_bds50(message: DF20 | DF21) -> bool:
return message.get("bds", None) == "50" or "bds50" in message
def is_bds60(message: DF20 | DF21) -> bool:
return message.get("bds", None) == "60" or "bds60" in message
def is_bds61(message: DF17) -> TypeGuard[DF17_BDS61]:
return message.get("bds", None) == "61" or "bds61" in message
def is_bds62(message: DF17) -> TypeGuard[DF17_BDS62]:
return message.get("bds", None) == "62" or "bds62" in message
def is_bds65(message: DF17) -> TypeGuard[DF17_BDS65]:
return message.get("bds", None) == "65" or "bds65" in message
class Flarm(TypedDict):
timestamp: int
reference_lat: float
reference_lon: float
icao24: str
is_icao24: bool
actype: Literal[
"Unknown",
"Glider",
"Towplane",
"Helicopter",
"Parachute",
"DropPlane",
"Hangglider",
"Paraglider",
"Aircraft",
"Jet",
"UFO",
"Balloon",
"Airship",
"UAV",
"Reserved",
"StaticObstacle",
]
latitude: float
longitude: float
geoaltitude: int
vertical_speed: float
groundspeed: float
track: float
no_track: bool
stealth: bool
gps: int