smartCARS 3 introduced a scriptable flight tracking system that allows for deep customization of tracking behavior. This script is editable via smartCARS Central. This document will explain how to write the scripts, give some important information on how to expect it to behave, and provide a list of possible variables and syntax instructions.
The tracking configuration is a JSON object that contains an array of tracking events. An example of a configuration that only logs when pushback begins is below.
{
"events": [
{
"condition": "{phase} equals 'PUSH_BACK'",
"message": "Pushing back with {fuelTotalQuantityWeight} {weightUnits} of fuel",
"initialValue": false,
"timeout": 0
}
]
}
The fields are as follows:
condition
: the code string that smartCARS should evaluate to determine if this event is occurringmessage
: the templated string that will logged to smartCARS when the conditions have been metinitialValue
: this optional field allows you to specify the initial value smartCARS should be expecting - this is used to prevent log items such as "engines off" when you first start the flighttimeout
: this optional field tells smartCARS to ensure the condition remains met for the specified number of milliseconds - this helps prevent log items like "flaps set to 1", "flaps set to 2", back to back and instead only captures the final positionWhen the condition is met, the message
value is parsed by smartCARS and any variables in the string are replaced with the actual data at that time. For example, the above message might generate something like
Pushing back with 12516 lbs of fuel
when the conditions are met.
The condition
field has a relatively strict but simple syntax. The basic format is as follows:
Syntax | Example |
---|---|
{variable} comparison {reference} |
{engine1Firing} equals false |
If you need more than one variable evaluation, you can use and
and or
as joiners. Note that smartCARS has no concept of an order of operations and evaluates all conditions left to right. The syntax for that is:
Syntax | Example |
---|---|
{variable} comparison {reference} joiner {variable} comparison {reference} |
{engine2Firing} not_equals false and {enginesCount} greater_than 1 |
Finally, you may want to log only when a variable changes (or increases/decreases). To accomplish this:
Syntax | Example |
---|---|
{variable} changed |
{flapsControl} changed |
We recommend using a
timeout
value on mostchanged
events to reduce the likelihood of log spam, a scenario where extremely frequent changes in the variable cause excessive amounts of logging.
The possible comparisons that accept a reference variable:
greater_than
less_than
equals
not_equals
increased_by
decreased_by
The possible comparisons that do not accept a variable but compare to their own previous value:
changed
increased
decreased
Certain variables are string types. To compare to a string instead of a number, simply wrap the reference in single quotes. For example, a condition that becomes true when we first receive a valid aircraft name would be {aircraftName} not_equals ''
.
The message
field has no syntax requirements with the exception of only using valid, existing variables from the list below.
Best practices are:
Below is a list of variables that are accessible to the flight tracking.
The variables will be converted to the user's preferred units when parsed for a message only. All comparisons and evaluations of the conditions are done in pounds, feet, and nautical miles.
Variable | Description |
---|---|
{latitude} |
Decimal latitude |
{longitude} |
Decimal longitude |
{altitude} |
Altitude MSL |
{altitudeAgl} |
Altitude AGL |
{bank} |
Degrees bank (left is negative) |
{heading} |
True heading |
{pitch} |
Degrees pitch (down is negative) |
{gs} |
Ground speed in knots |
{gearControl} |
Boolean indicating gear down (true when down) |
{flapsControl} |
Number representing flaps detent number |
{vs} |
Vertical speed in feet per minute |
{tas} |
True airspeed in knots |
{clockHour} |
Local simulation hour (24 hour) |
{clockMin} |
Local simulation minute |
{clockSec} |
Local simulation second |
{zuluHour} |
Zulu simulation hour (24 hour) |
{zuluMin} |
Zulu simulation minute |
{zuluDayOfMonth} |
Zulu simulation day of the month (1-31) |
{zuluMonthOfYear} |
Zulu simulation month of the year (1-12) |
{zuluYear} |
Zulu year |
{localDayOfMonth} |
Local simulation day of the month (1-31) |
{localMonthOfYear} |
Local simulation month of the year (1-12) |
{localYear} |
Local simulation year |
{planeOnground} |
Boolean indicating on ground (true on ground) |
{enginesCount} |
Number indicating number of engines |
{engine1Firing} |
Boolean indicating engine 1 status (true is on) |
{engine2Firing} |
Boolean indicating engine 2 status (true is on) |
{engine3Firing} |
Boolean indicating engine 3 status (true is on) |
{engine4Firing} |
Boolean indicating engine 4 status (true is on) |
{ias} |
IAS in knots |
{gForceTouchDown} |
G-forces at touchdown |
{landingRate} |
Landing rate in feet per minute |
{simulatorVersion} |
Simulator version string |
{aircraftType} |
Aircraft type string |
{aircraftEmptyWeight} |
Empty weight of the aircraft |
{zeroWeightPlusPayload} |
The zero fuel weight of the aircraft |
{pauseFlag} |
Boolean indicating pause (true when paused) |
{slewMode} |
Boolean indicating slew mode (true in slew) |
{simulationRate} |
Simulation rate |
{stallWarning} |
Boolean indicating stall (true when stalling) |
{overspeedWarning} |
Boolean indicating overspeed (true when overspeeding) |
{isInMenu} |
Boolean indicating menu |
{engine1N1} |
Engine 1 N1 |
{engine2N1} |
Engine 2 N1 |
{engine3N1} |
Engine 3 N1 |
{engine4N1} |
Engine 4 N1 |
{engine1N2} |
Engine 1 N2 |
{engine2N2} |
Engine 2 N2 |
{engine3N2} |
Engine 3 N2 |
{engine4N2} |
Engine 4 N2 |
{fuelTotalQuantityWeight} |
Total fuel quantity weight |
{windDirection} |
Wind direction in degrees |
{windSpeed} |
Wind speed in knots |
{flapsRightPosition} |
Percentage of left flaps |
{flapsLeftPosition} |
Percentage of right flaps |
{pressureQNH} |
Pressure setting in millibars |
{altimeterSettings} |
Altimeter setting in millibars |
{transponderFreq} |
Transponder (squawk) code |
{com1Freq} |
Com 1 frequency |
{nav1Freq} |
Nav 1 frequency |
{nav2Freq} |
Nav 2 frequency |
{com2Freq} |
Com 2 frequency |
{isXPlane} |
Boolean indicating if the simulator is X-Plane |
{weightUnits} |
User weight unit setting ('kgs' or 'lbs') |
{altitudeUnits} |
User altitude unit setting ('kgs' or 'lbs') |
{landingDistanceUnits} |
User landing distance unit setting ('ft' or 'm') |
{milesToGo} |
Nautical miles to the arrival |
{cruiseAltitude} |
Current assumed cruising altitude |
{landingDistance} |
The distance of the landing rollout |
{phase} |
The current flight phase data string ('PUSH_BACK', 'TAXI_TO_GATE', etc.) |
{fuelUsed} |
The amount of fuel used in the flight |
{simbriefFlightTimeDelta} |
The offset from the expected flight time (using SimBrief) |
{simbriefFuelUsedDelta} |
The offset from the expected fuel usage (using SimBrief) |
{phaseString} |
The flight phase string (push back, taxi to gate) |
{drashed} |
Detect whether the aircraft has crashed |
Once you have your script ready, log in to smartCARS Central and navigate to the Community Editor.
Select the community you are editing (if applicable), ensure the Flight Tracking plugin by TFDi Design is installed, then expand the "Flight Tracking" plugin row by clicking its name.
When ready, simply paste your new tracking configuration into the "Logger Configuration" box and click "Update". If there is any issue with the formatting, smartCARS Central will indicate this.
If the script is simply too large, you can minify it first to remove unneeded whitespace or padding. To do this, you can use any online minifier tool like the Code Beautify JSON Minifier.
Although it is reversible, we recommend keeping a non-minified copy of your configuration to make editing easier.
Below is the default flight tracking configuration as of version 0.10.0beta of smartCARS 3.
{
"events": [
{
"condition": "{simulatorVersion} not_equals ''",
"message": "Using {simulatorVersion}"
},
{
"condition": "{aircraftType} not_equals ''",
"message": "Flying {aircraftType}"
},
{
"condition": "{aircraftType} changed",
"message": "Aircraft changed to {aircraftType}"
},
{
"condition": "{crashed} changed",
"message": "Aircraft crashed"
},
{
"condition": "{engine1Firing} not_equals false",
"message": "Engine 1 On"
},
{
"condition": "{engine1Firing} equals false",
"message": "Engine 1 Off",
"initialValue": true
},
{
"condition": "{engine2Firing} not_equals false and {enginesCount} greater_than 1",
"message": "Engine 2 On"
},
{
"condition": "{engine2Firing} equals false and {enginesCount} greater_than 1",
"message": "Engine 2 Off",
"initialValue": true
},
{
"condition": "{engine3Firing} not_equals false and {enginesCount} greater_than 2",
"message": "Engine 3 On"
},
{
"condition": "{engine3Firing} equals false and {enginesCount} greater_than 2",
"message": "Engine 3 Off",
"initialValue": true
},
{
"condition": "{engine4Firing} not_equals false and {enginesCount} greater_than 3",
"message": "Engine 4 On"
},
{
"condition": "{engine4Firing} equals false and {enginesCount} greater_than 3",
"message": "Engine 4 Off",
"initialValue": true
},
{
"condition": "{flapsControl} changed",
"message": "Flaps set to {flapsControl}%"
},
{
"condition": "{gearControl} not_equals 0",
"message": "Gear lever lowered",
"initialValue": true
},
{
"condition": "{gearControl} equals 0",
"message": "Gear lever raised"
},
{
"condition": "{pauseFlag} equals true",
"message": "Paused"
},
{
"condition": "{pauseFlag} not_equals true",
"message": "Unpaused",
"initialValue": true
},
{
"condition": "{slewMode} equals true",
"message": "Slew mode entered"
},
{
"condition": "{slewMode} not_equals true",
"message": "Slew mode left",
"initialValue": true
},
{
"condition": "{simulationRate} changed",
"message": "Sim rate changed to {simulationRate}x"
},
{
"condition": "{stallWarning} equals true",
"message": "Stalling"
},
{
"condition": "{stallWarning} equals true and {ias} decreased",
"message": "Reached minimum speed of {ias} kts",
"timeout": 5000
},
{
"condition": "{stallWarning} not_equals true",
"message": "Stall recovered",
"initialValue": true
},
{
"condition": "{overspeedWarning} equals true",
"message": "Overspeeding"
},
{
"condition": "{overspeedWarning} equals true and {ias} increased",
"message": "Reached maximum speed of {ias} kts",
"timeout": 5000
},
{
"condition": "{overspeedWarning} not_equals true",
"message": "No longer overspeeding",
"initialValue": true
},
{
"condition": "{altitude} less_than 10000 and {ias} greater_than 254 and {ias} increased and {slewMode} equals false",
"message": "Reached {ias} kts below 10,000 feet",
"timeout": 5000
},
{
"condition": "{bank} greater_than 30 or {bank} less_than -30",
"message": "Bank exceeded 30 degrees",
"timeout": 1000
},
{
"condition": "{pitch} greater_than 20",
"message": "Pitch exceeded 20 degrees nose up",
"timeout": 1000
},
{
"condition": "{pitch} less_than -10",
"message": "Pitch exceeded 10 degrees nose down",
"timeout": 1000
},
{
"condition": "{fuelTotalQuantityWeight} increased_by 1000 and {planeOnground} equals false",
"message": "Fuel increased by 1000 to {fuelTotalQuantityWeight} {weightUnits}"
},
{
"condition": "{fuelTotalQuantityWeight} decreased_by 1000 and {planeOnground} equals true",
"message": "Fuel decreased by 1000 to {fuelTotalQuantityWeight} {weightUnits}"
},
{
"condition": "{phase} equals 'BOARDING'",
"message": "Now boarding"
},
{
"condition": "{phase} equals 'PUSH_BACK'",
"message": "Pushing back with {fuelTotalQuantityWeight} {weightUnits} of fuel"
},
{
"condition": "{phase} equals 'TAXI'",
"message": "Taxiing out"
},
{
"condition": "{phase} equals 'TAKE_OFF'",
"message": "Taking off"
},
{
"condition": "{phase} equals 'REJECTED_TAKE_OFF'",
"message": "Takeoff rejected"
},
{
"condition": "{phase} equals 'CLIMB'",
"message": "Climbing at {ias} kts, {pitch} degrees pitch, {bank} degrees bank"
},
{
"condition": "{phase} equals 'CRUISE'",
"message": "Cruising at {cruiseAltitude} {altitudeUnits}"
},
{
"condition": "{phase} equals 'DESCENT'",
"message": "Descending with {milesToGo} nm to go"
},
{
"condition": "{phase} equals 'APPROACH'",
"message": "Approach started at {altitudeAgl} {altitudeUnits} AGL with {milesToGo} nm to go"
},
{
"condition": "{phase} equals 'FINAL'",
"message": "On final at {altitudeAgl} {altitudeUnits} with {milesToGo} nm to go at {ias} kts, {pitch} degrees pitch, {bank} degrees bank"
},
{
"condition": "{phase} equals 'LANDED' and {planeOnground} equals true",
"message": "Touched down at {landingRate} fpm, {gForceTouchDown}g, {ias} kts, {pitch} degrees pitch, {bank} degrees bank"
},
{
"condition": "{phase} equals 'GO_AROUND'",
"message": "Going around at {altitudeAgl} {altitudeUnits} AGL, {ias} kts, {pitch} degrees pitch, {bank} degrees bank"
},
{
"condition": "{phase} equals 'TAXI_TO_GATE'",
"message": "Taxiing to gate, landed in {landingDistance} {landingDistanceUnits}"
},
{
"condition": "{transponderFreq} not_equals 0 and {com1Freq} not_equals 0 and {com2Freq} not_equals 0 and {nav1Freq} not_equals 0 and {nav2Freq} not_equals 0",
"message": "COM1: {com1Freq}, COM2: {com2Freq}, NAV1: {nav1Freq}, NAV2: {nav2Freq}, Transponder: {transponderFreq}"
},
{
"condition": "{transponderFreq} changed",
"message": "Transponder code set to {transponderFreq}",
"timeout": 1000
},
{
"condition": "{com1Freq} changed",
"message": "COM1 active frequency set to {com1Freq}",
"timeout": 1000
},
{
"condition": "{com2Freq} changed",
"message": "COM2 active frequency set to {com2Freq}",
"timeout": 1000
},
{
"condition": "{nav1Freq} changed",
"message": "NAV1 active frequency set to {nav1Freq}",
"timeout": 1000
},
{
"condition": "{nav2Freq} changed",
"message": "NAV2 active frequency set to {nav2Freq}",
"timeout": 1000
},
{
"condition": "{phase} equals 'LANDED' and {milesToGo} greater_than 10",
"message": "On ground {milesToGo} nm from planned arrival airport"
}
]
}