There are a few ways to access LiveTraffic's aircraft data programmatically:
LiveTraffic offers a C++ API to read (nearly) all information of all aircraft that LiveTraffic operates. With a single call, you are provided with a vector of
LTAircraft objects. You can subclass the
LTAircraft class to add your own management functionality. Technically, data is packed and transferred very efficiently in the background and transferred by means of binary dataRefs. Available from X-Plane.org and from GitHub. Includes a sample plugin implementation demonstrating most features.
I am aware of one plugin, which makes already active use of it, which is ABC.
As of X-Plane 11.50, X-Plane offers a new approach called TCAS Override to report planes to TCAS systems and to other plugins interested in multiplayer aircraft informaton. New plugins shall definitely follow this new approach. Find implementaton details in Laminar's blog entry.
While LiveTraffic has TCAS control, and only then, LiveTraffic reports the closest up to 63 aircraft as TCAS targets with the following values:
24 bit Mode S transponder code
Flight number or, if unavailable, tail number (registration)
ICAO aircraft type designator
All dataRefs under
sim/cockpit2/tcas/targets/position are filled as expected and documented except for the following, which are not populated:
The classic 19 sets of multiplayer dataRefs (
sim/multiplayer/position/plane*) are mirrored automatically while providing TCAS target information. So the closest 19 aircraft are also available via this channel while LiveTraffic has TCAS control.
With TCAS Override,
XPLMCountAircraft returns the actual number of reported aircraft independend of how many AI Aircraft the user has configured. So you can rely on this number and don't necessarily need to always monitor all these 19 slots. Still, for backward compatibility, LiveTraffic fills unused slots'
_x/y/z values with
> 9999999. (They are deliberately not set to
0 in this case, because 0/0/0 is a totally valid geographic location.)
As a supplement to the standard multiplay dataRefs, textual aircraft and flight information is provided via shared dataRefs of type
xplmType_Data as suggested by FSTramp (LiveTraffic issue #144) with
# being a plane number between
sim/multiplayer/position/plane#_tailnum - Tail number, registration
sim/multiplayer/position/plane#_ICAO - ICAO Aircraft type
sim/multiplayer/position/plane#_manufacturer - Aircraft manufacturer, human readable
sim/multiplayer/position/plane#_model - Aircraft model, human readable
sim/multiplayer/position/plane#_ICAOairline - ICAO airline/operator code
sim/multiplayer/position/plane#_airline - Airline/operator
sim/multiplayer/position/plane#_flightnum - Flight number
sim/multiplayer/position/plane#_apt_from - Origin airport
sim/multiplayer/position/plane#_apt_to - Destination airport
sim/multiplayer/position/plane#_cslModel - CSL model used to render the plane (folder name plus model id)
A plugin wanting to use this data must call
XPLMShareData, can optionally thereby register a notification callback, then calls
XPLMGetDatab as usual. Provide at least a 40 character buffer per dataRef to be on the safe side.
A LiveTraffic user can activate a camera view on any aircraft. LiveTraffic publishes which aircraft the camera shows and even provides a setting that disables LiveTraffic's internal camera implementation so that a 3rd party camera tool can instead provide the view.
LiveTraffic operates two integer shared dataRefs with global names, ie. not LiveTraffic-specific. In fact, they pick up the naming scheme as used by the shared dataRefs for textual aircraft information. Shared dataRefs have the advantage that a reading plugin can register a notification callback and several plugins can write to them and this way inform both the camera plugin as well as LiveTraffic. See SDK documentation on XPLMShareData.
sim/multiplayer/camera/tcas_idx is set to the TCAS index (
1..63) of the aircraft being viewed, or to
-1 if that aircraft has no TCAS index, or to
0 if camera view is turned off.
sim/multiplayer/camera/modeS_id is set to the aircraft key, usually the 24bit ICAO transponder code (like
11211316) of the aircraft being viewed, or to
0 if camera view is turned off.
A camera plugin
should register a notification on
sim/multiplayer/camera/tcas_idx because this dataRef is set last. By the time your notification callback triggers both
tcas_idx will be updated.
should, in the notification callback, read one or both values and do your camera magic if values are not
can - optionally but welcome - write the dataRef values, too, ie. if your user switches off the camera view then update
tcas_idx (in this order) to
0 to indicate that no camera view is on an aircraft; or even update them with aircraft info if your user selects another aircraft inside your plugin. (Note that your callbacks get called even if you set the values...weird twist of the SDK implementation.)
Alternatively, a camera plugin can just use LTAPI, which handles all that internally:
LTAPIAircraft::toggleCamera(), which is called whenever the shared dataRef values change on the current aircraft and even provides you with a pointer to the previous aircraft if any. The LTAPIExample plugin includes an example implementation.
LTAPIConnect::clearCameraInfo() are available for write operations.
You can make use of the data broadcasted on the ForeFlight channel for other purposes than just ForeFlight. The ForeFlight data format is described here and LiveTraffic sticks to it. Example broadcasts (around OMDB) look like this:
Example ForeFlight broadcast datagramsXGPSLiveTraffic,55.367,25.256,240.6,119.235,52.2XATTLiveTraffic,119.3,1.8,-0.5XTRAFFICLiveTraffic,4921470,25.269,55.200,5023.0,0.0,1,289.6,208.9,SWR243XTRAFFICLiveTraffic,7701531,25.252,55.359,9.9,0.0,0,123.0,14.9,CEB015XTRAFFICLiveTraffic,8994918,25.157,55.366,6707.5,2711.5,1,273.7,266.6,GFA513XTRAFFICLiveTraffic,9003216,25.245,55.366,36.9,0.0,0,253.2,11.2,UAE529
User plane's position is broadcasted with 1Hz, its attitude with 5Hz. The repeat interval of traffic data is not defined by ForeFlight and configurable in LiveTraffic.
Output port is 49002 as defined by ForeFlight. There is no GUI setting for it so that nobody can accidently change it. But you'll find it in LiveTraffic's configuration file.
Here's a simplistic Python script, with which I test receiving any broadcasts. It does not interpret the data, but only displays it together with a timestamp. It works for Python 2 and 3 (only the output format slightly differs) and takes just one parameter, the port number:
udp_listen.py#!/usr/bin/pythonimport sysimport socketimport time#---socket creationconnexion = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)connexion.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)if sys.platform != "win32":connexion.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)#---Bindtry:connexion.bind(('', int(sys.argv)))except socket.error:print ("connexion failed")connexion.close()sys.exit()#---wait for and print datawhile 1:data, addr = connexion.recvfrom(1024)print (time.time(), ":", data)
./udp_listen.py 49002, it would output received UDP datagrams continuously like this:
Example Output of udp_listen.py(1554490061.876467, ':', 'XTRAFFICLiveTraffic,3958292,50.021,8.430,1569.0,-1146.4,1,69.6,186.4,DLH805')(1554490061.876575, ':', 'XTRAFFICLiveTraffic,3958350,50.035,8.545,324.9,0.0,0,58.1,2.3,DLH2VH')(1554490061.876621, ':', 'XTRAFFICLiveTraffic,3958370,50.043,8.522,350.3,0.0,0,70.4,59.8,DLH8A')(1554490061.878866, ':', 'XTRAFFICLiveTraffic,3958394,50.048,8.570,366.6,0.0,0,0.0,0.0,DLH5MR')(1554490061.889803, ':', 'XGPSLiveTraffic,8.583,50.032,106.5,180.000,0.0')(1554490061.891284, ':', 'XTRAFFICLiveTraffic,3957833,50.042,8.582,358.0,0.0,0,27.2,12.4,DLH21U')(1554490061.900316, ':', 'XTRAFFICLiveTraffic,3958441,50.044,8.536,341.7,0.0,0,81.9,30.8,DLH1449')(1554490061.923233, ':', 'XTRAFFICLiveTraffic,3958443,50.045,8.569,360.9,0.0,0,270.0,0.0,DLH57F')(1554490061.944078, ':', 'XTRAFFICLiveTraffic,3958499,50.043,8.561,351.1,0.0,0,162.2,11.5,DLH044')(1554490061.95145, ':', 'XATTLiveTraffic,114.3,-1.3,0.2')(1554490061.964778, ':', 'XTRAFFICLiveTraffic,3958610,50.072,8.526,23984.0,135.9,1,335.5,332.7,EWG1910')(1554490061.987202, ':', 'XTRAFFICLiveTraffic,3958617,50.040,8.575,347.0,0.0,0,60.1,24.4,DLH9KL')(1554490061.992343, ':', 'XTRAFFICLiveTraffic,3958157,50.043,8.547,342.5,0.0,0,145.1,22.6,DLH087')(1554490062.009156, ':', 'XTRAFFICLiveTraffic,3960929,50.041,8.562,345.9,0.0,0,248.7,9.7,GEC8343')(1554490062.029472, ':', 'XTRAFFICLiveTraffic,4458944,50.039,8.555,339.9,0.0,0,247.5,20.5,EJU25DA')(1554490062.05433, ':', 'XTRAFFICLiveTraffic,4566062,50.049,8.589,359.1,0.0,0,342.2,4.1,SAS1636')(1554490062.076019, ':', 'XTRAFFICLiveTraffic,4920849,50.029,8.542,452.8,-1150.5,1,69.9,125.7,SWR1076')(1554490062.094481, ':', 'XATTLiveTraffic,114.3,-1.3,0.2')(1554490062.098079, ':', 'XTRAFFICLiveTraffic,4921315,50.041,8.559,343.6,0.0,0,0.0,0.0,SWR106U')(1554490062.121316, ':', 'XTRAFFICLiveTraffic,5270561,50.032,8.526,324.9,0.0,0,190.1,20.1,ADR125')(1554490062.145733, ':', 'XTRAFFICLiveTraffic,7786223,49.952,8.592,8000.0,0.0,1,249.1,280.6,SIA326')(1554490062.152416, ':', 'XATTLiveTraffic,114.3,-1.3,0.2')(1554490062.167006, ':', 'XTRAFFICLiveTraffic,7867067,50.060,8.653,2733.6,682.0,1,71.9,228.2,CPA282')(1554490062.197146, ':', 'XTRAFFICLiveTraffic,3958217,50.049,8.570,368.4,0.0,0,0.0,0.0,DLH892')(1554490062.299546, ':', 'XTRAFFICLiveTraffic,3958350,50.035,8.545,324.9,0.0,0,58.1,2.3,DLH2VH')(1554490062.354267, ':', 'XATTLiveTraffic,114.3,-1.3,0.2')(1554490062.403429, ':', 'XTRAFFICLiveTraffic,3958441,50.044,8.536,341.7,0.0,0,81.9,30.8,DLH1449')(1554490062.504334, ':', 'XTRAFFICLiveTraffic,3958443,50.045,8.569,360.9,0.0,0,270.0,0.0,DLH57F')(1554490062.55615, ':', 'XATTLiveTraffic,114.3,-1.3,0.2')(1554490062.608154, ':', 'XTRAFFICLiveTraffic,3958610,50.072,8.526,23984.0,135.9,1,335.5,332.7,EWG1910')(1554490062.693573, ':', 'XGPSLiveTraffic,8.583,50.032,106.5,180.000,0.0')(1554490062.710873, ':', 'XTRAFFICLiveTraffic,3960929,50.041,8.562,345.9,0.0,0,248.7,9.7,GEC8343')(1554490062.757548, ':', 'XATTLiveTraffic,114.3,-1.3,0.2')(1554490062.915558, ':', 'XTRAFFICLiveTraffic,4921315,50.041,8.559,343.6,0.0,0,0.0,0.0,SWR106U')(1554490062.96226, ':', 'XATTLiveTraffic,114.3,-1.3,0.2')(1554490063.018004, ':', 'XTRAFFICLiveTraffic,7786223,49.952,8.592,8000.0,0.0,1,249.1,280.6,SIA326')(1554490063.120083, ':', 'XTRAFFICLiveTraffic,7867067,50.060,8.653,2733.6,682.0,1,71.9,228.2,CPA282')(1554490063.162793, ':', 'XATTLiveTraffic,114.3,-1.3,0.2')(1554490063.220842, ':', 'XATTLiveTraffic,114.3,-1.3,0.2')(1554490063.364389, ':', 'XATTLiveTraffic,114.3,-1.3,0.2')(1554490063.564868, ':', 'XATTLiveTraffic,114.3,-1.3,0.2')
The RealTraffic channel receives data from a local app, the RealTraffic app, which sends it out via UDP. Any other program can send the same kind of UDP data and LiveTraffic would just use it as well.
This paragraph might need more details...but a well working proof of concept that I use when testing LiveTraffic's handling of aircraft is discussed in this forum thread.
SendTraffic.py is a Python 3 script, which takes a well-formatted CSV as input and sends each line to LiveTraffic using the RealTraffic port. In LiveTraffic, the RealTraffic channel must be enabled. Run
SendTraffic.py -h to see all options.
Here are some sample files I also use for testing LiveTraffic in reproducible scenarios, the file names give away the airport you need to be at to see something happening: