Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

msfs-simconnect-api-wrapper

Pomax200CC0-1.04.6.2

A convenient SimConnect API for playing with Microsoft Flight Simulator 2020

simconnect, msfs, msfs2020, node

readme

msfs-simconnect-api-wrapper

A JavaScripty wrapper around EvenAR's excellent node-simconnect with a simplified API.

See test.js for the basics, which you can run (with MSFS open and sitting on the apron with a plane =) using npm test.

Versioning

This library uses strict semver versioning. The current version of this library is 4.5.0. See the changelog for the full version history.

Installation and use

Install with npm install msfs-simconnect-api-wrapper.

For examples on how to use this, see the examples dir.

API

This API manager has an argless constructor that does nothing other than allocate internal values. In order to work with MSFS, you need to call the connect function first, which can take an options object of the following form:

{
  autoReconnect: true or false (will try to reconnect to MSFS if the connection gets closed), defaults to `false`.
  retries: positive number or Infinity, defaults to 0.
  retryInterval: positive number, representing number of seconds (not milliseconds) between retries, defaults to 2.
  onConnect: callback function with the node-simconnect handle as its only argument.
  onRetry: callback function with (retries left, retry interval) as its two arguments. This triggers _before_ the next attempt is scheduled.
  onException: callback function with (exceptionName) as argument.
  host: a domain or IP string (e.g. "localhost" or "127.0.0.1", default: "0.0.0.0").
  port: the port at which to contact MSFS (default: 500).
}

For example, we can set up an API object and have it start trying to connect, eventually dropping us into the code that knows it has an MSFS connection using the following boilerplate:

import { MSFS_API } from "./msfs-api.js";

const api = new MSFS_API();

api.connect({
  retries: Infinity,
  retryInterval: 5,
  onConnect: () => run(),
  onRetry: (_, interval) => {
    console.log(`Connection failed: retrying in ${interval} seconds.`);
  },
});

function run() {
  console.log(`We have an API connection to MSFS!`);
  //
  // ...your code here...
  //
}

Secondary exports

The API also offers the following exports:

  • loadAirportDB() is a function that will load the airport database and return it as array of airports.
  • SystemEvents The symevent object that the API uses for registering and removing event listeners using on and off.
  • MSFS_NOT_CONNECTED A constant that the API uses for its "not connected" error. You should never need this.

Properties

The API has a single property .connected which is either undefined or true and can be used to determine whether the API has a connection to MSFS outside of code that relies on the onConnect callback.

Methods

connect(opts?)

Sets up a connection to MSFS, see above for an explanation of opts. If let unspecified, no retries will be attempted.

on(evtDefinition, handler)

Starts listening for a specific simconnect event with a specific handler. Returns a corresponding arg-less off() function to clean up the listener. See the "System events" section below for details on the event definition.

System events (used for on/off handling):

All event names in https://docs.flightsimulator.com/html/Programming_Tools/SimConnect/API_Reference/Events_And_Data/SimConnect_SubscribeToSystemEvent.htm are supported as constants on the SystemEvents object, importable alongside MSFS_API:

import { SystemEvents, MSFS_API } from "./msfs-api.js";

const api = new MSFS_API();

api.connect({
  retries: Infinity,
  retryInterval: 5,
  onConnect: () => {
    api.on(SystemEvents.PAUSED, () => {
      // ...
    });
  },
});

Note that the event names are keys from the SystemEvents object, using UPPER_SNAKE_CASE, not strings.

Special Events

There are currently two non-simconnect events that can be listened to:

  • AIRPORTS_IN_RANGE, registers a listener for notifications about airports coming into range of our airplane (or rather, coming into range of "the current Sim bubble", which is all world tiles currently loaded and active in the sim).
  • AIRPORTS_OUT_OF_RANGE, registers a listener for notifications about airports dropping out of range of our airplane (with the same note as above).

off(evtDefinition, handler)

Stop listening for a specific simconnect event with a specific handler. You'll typically not need to call this function directly, as you can just use the function that on returns. See the "System events" section above for more details on the event definition.

get(...propNames)

Accepts a list of simvars (with spaces or underscores) and async-returns a key/value pair object with each simvar as key (with spaces replaced by underscores).

special (non-simconnect) variables

There are a number of special variables that can only be retrieved using a get call with a single variable name, yielding data that is not serviced by SimConnect's own variables (or data that requires a considerable amount of low-level event handling).

There are currently three variables:

  • ALL_AIRPORTS, which yields the list of all airports known to MSFS.
  • NEARBY_AIRPORTS, which yields the list of airports that are currently in range of our airplane (or rather, in range of "the current Sim bubble", which is all world tiles currently loaded and active in the sim).
  • NEARBY_AIRPORTS:NM, which yields the list of airports within a radius of NM nautical miles around the airplane's location.
  • AIRPORT:index, which yields an airport's information (including runway information), with index being the airport's ICAO code.

The first three return arrays of Airport object, the last one returns a single Airport object

Airport objects have the following shape:

{
  latitude: number in degrees
  longitude: number in degrees
  altitude: number in feet
  declination: when the magnetic compass says 360, what true heading are we on, in degrees
  name: airport name as a string with at most 32 characters
  name64: airport name as a string with at most 64 characters
  icao: four character ICAO code for this airport
  region: the ICAO region for this airport as string
  runwayCount: number of runways at this airport
  runways: array of runway objects
}

Runway objects have the following shape:

{
  altitude: number in feet
  approach: array of runway approaches
  bbox: array with the runway's corner points encoded as [lat,long]
  end: [lat, long, alt] coordinate for the runway end
  heading: number in degrees
  latitude: number in degrees, marking the center of the runway
  length: number in meters
  longitude: number in degrees, marking the center of the runway
  patternAltitude: number in meters
  slope: number in degrees
  slopeTrue: number in degrees
  start: [lat, long, alt] coordinate for the runway start
  surface: surface material, as string
  width: number in meters
}

Approaches gave the following shape:

{
  designation: runway designation as string
  marking: runway marking, as string (can be a number, or cardinal direction)
  heading: true approach heading, in degrees
  ILS: {
    type: ILS type as string
    icao: ICAO code for this approach's ILS
    region": ICAO region for this approach's ILS
  }
}

schedule(handler, interval, ...propNames)

Sets up a periodic call to handler every interval milliseconds with the result of get(...propNames). Returns an arg-less off() to end the scheduled call.

periodic(handler, period, ...propNames)

similar to schedule, but using MSFS's own timing constants rather than specifying a certain number of milliseconds. These can be found over on the official documentation page but are reproduced here (always check the website to make sure the information here isn't out of date though!). Note that the offical SDK versions have a SIMCONNECT_PERIOD_ prefix which is not used in this library:

Constant Description
NEVER Specifies that the data is not to be sent.
ONCE Specifies that the data should be sent once only. Note that this is not an efficient way of receiving data frequently, use one of the other periods if there is a regular frequency to the data request.
VISUAL_FRAME Specifies that the data should be sent every visual (rendered) frame.
SIM_FRAME Specifies that the data should be sent every simulated frame, whether that frame is rendered or not.
SECOND Specifies that the data should be sent once every second.

You can access these constants through the SimConnectPeriod export:

import { MSFS_API, SimConnectPeriod } from "msfs-simconnect-api-wrapper";

const api = new MSFS_API();
api.connect({
  ...
  onConnect: () => {
    api.period(..., SimConnectPeriod.VISUAL_FRAME, ...);
  }
});

set(propName, value)

Accepts a single simvar and the value its should be set to. This will throw "SimVar ... is not settable" when attempting to set the value for a read-only variable.

trigger(triggerName, value?)

Triggers a simconnect event, with optional value.

Supported Simvars:

All simvars are supported, barring several simvars with data types for which I need to figure out how to actually deference then, such as LatLonAlt structs, or the (super rare) bool/string combination, as well a any simvar that is officially deprecated, or marked as "legacy, do not use these going forward". If you get an error about an unknown Simvar, look up that variable on the SimConnect variables list and see if it's either deprecated, or part of a collection that is considered legacy.

  • <input checked="" disabled="" type="checkbox"> Camera Variables (not verified)
  • <input checked="" disabled="" type="checkbox"> Services Variables (not verified)
  • <input checked="" disabled="" type="checkbox"> Miscellaneous Variables (not verified)
  • Aircraft SimVars:
    • <input checked="" disabled="" type="checkbox"> Aircraft Autopilot/Assistant Variables (not verified)
    • <input checked="" disabled="" type="checkbox"> Aircraft Brake/Landing Gear Variables (not verified)
    • <input checked="" disabled="" type="checkbox"> Aircraft Control Variables (not verified)
    • <input checked="" disabled="" type="checkbox"> Aircraft Electrics Variables (not verified)
    • <input checked="" disabled="" type="checkbox"> Aircraft Engine Variables (not verified)
    • <input checked="" disabled="" type="checkbox"> Aircraft Flight Model Variables (not verified)
    • <input checked="" disabled="" type="checkbox"> Aircraft Fuel Variables (not verified)
    • <input checked="" disabled="" type="checkbox"> Aircraft Misc. Variables (not verified)
    • <input checked="" disabled="" type="checkbox"> Aircraft Radio Navigation Variables (not verified)
    • <input checked="" disabled="" type="checkbox"> Aircraft System Variables (not verified)
    • <input checked="" disabled="" type="checkbox"> Helicopter Variables (not verified)

Further more, all environment variables listed over on https://docs.flightsimulator.com/html/Additional_Information/Reverse_Polish_Notation.htm#EnvironmentVariables are supported as well.

(note: "not verified" means that they've been ported, marked settable where appropriate, pass the test run, but they've not been individually confirmed to be correct with respect to the documentation yet).

Supported SimEvents:

SimEvents are resolved by key name, so as long as you use a valid key name, you can trigger it.

See https://docs.flightsimulator.com/html/Programming_Tools/Event_IDs/Event_IDs.htm for the full list (there are... a lot).

Regenerating the airport list

It's conceivable that this API library becomes poorly maintained, or abandoned. In that case, the airport list will go out of sync with the in-game data. If and when that happens, you can trivially (but not quickly) regenerate the airport data by:

  1. first, deleting the airport.db.gz file in your node_modules/msfs-simconnect-api-wrapper directory, then
  2. making sure MSFS is running, then
  3. run any code that creates an instance of the MSFS API.

This will kick off a database regeneration pass, which will take a while to finish since it's processing data for 44,000+ airports, querying the details for each and turning it into not just a JSON format, but with more, and easier to work with, data than MSFS's response for each airport is.

Thankfully, you will only need to do this once every time there's a sim update release, because the result is (obviously) cached to file, after which the airport data will be in-sync again and will load just as fast as before.

Helping out

File an issue if you want to help get this wrapper to 100% simvar and event support! Even if you just want to help verify a few variables, that's a few variables fewer that I'll need to run through =)

changelog

How this library is versioned

This library strictly adheres to semver's major.minor.patch versioning:

  • patch version changes indicate bug fixes and/or internal-only code changes,
  • minor version changes indicate new functionality that does not break backward compatibility,
  • major version changes indicate backward-incompatible external API changes, no matter how small.

Version history

v4.6.0 (6 September 2024)

  • Updated airports based on MSFS v1.37.19.0
  • added the .periodic() function for scheduling event updates using MSFS's built in interval identifiers rather than specifying your own interval in milliseconds.

v4.5.0 (16 February 2024)

  • Updated runway start and end points with an altitude value in the third array position.

v4.4.0 (16 February 2024)

  • Updated airports based on MSFS v1.36.2.0

v4.3.0 (19 December 2023)

  • Updated runway objects with their in-game start and end point, as well as the in-game runway bounding box, so that you don't have to do that work if you just want to visualize airports, or do runway related calculations.

v4.2.0

  • Added an export for loadAirportDB, so that you can directly load the airport data rather than having to go through the API. If you want to do that, of course.

v4.1.0

  • Added heading and trueHeading to runway approach objects, because having to write code that turns an approach marking into a heading is something you should not have to do, that's something an API should have already done for you.
  • Added instructions on how to regenerate the airport database file, in case that should ever be necessary for you to do manually.

v4.0.0

  • Fixed an issue with runway slope values being double-converted. This is a breaking change for any code that relied on runway slope.

v3.2.0

  • The airport data has been updated for MSFS2020 v1.35.21.0 (SU14)

v3.1.0

  • Airport code has been restored, in a radically different way internally, but with the same API as before.

The airport data is now stored in a bundled database file. If the bundled database and the in-game airport database different in the number of airports, you'll get a console warning that you'll probably want to update your version of msfs-simconnect-api-wrapper.

v3.0.0

  • The airport code has been disabled, because it's all kinds of broken at the moment, and needs to be redone.
  • you can now pass host and port values as part of the .connect() options.
  • you can now pass an onException handler as part of the .connect() options.

v2.3.0

v2.2.1

  • removed a rogue console.log from the reconnect code

v2.2.0

  • added an autoReconnect property to the connect() options. When true, this will try to automatically reconnect to MSFS if it happens to disappear/disconnect at any point. Note that this will retrigger onConnect.

v2.1.1

  • Added an explicit throw when calling on, trigger, get, set, and schedule when the API is not connected to MSFS. This would already throw, but only at the point where the simconnect DLL was asked to do things, which led to unnecessarily cryptic errors with unnecessarily deep stack traces.

v2.1

  • added fuel variables. They were missing despite the readme saying they were implemented.
  • added a catch for unknown vars so the code doesn't actually crash.

v2.0.1

  • fix exception on repeated airport:index calls.

v2.0.0

Added support for airport queries:

  • new special variables NEARBY_AIRPORTS, ALL_AIRPORTS, and AIRPORT:index where index is an ICAO code.
  • new events AIRPORTS_IN_RANGE and AIRPORTS_OUT_OF_RANGE.

Removes getSpecial in favour of get with a single variable argument

v1.4.1

  • <input checked="" disabled="" type="checkbox"> Camera Variables
  • <input checked="" disabled="" type="checkbox"> Services Variables
  • <input checked="" disabled="" type="checkbox"> Miscellaneous Variables
  • Aircraft SimVars:
    • <input checked="" disabled="" type="checkbox"> Aircraft Autopilot/Assistant Variables
    • <input checked="" disabled="" type="checkbox"> Aircraft Brake/Landing Gear Variables
    • <input checked="" disabled="" type="checkbox"> Aircraft Control Variables
    • <input checked="" disabled="" type="checkbox"> Aircraft Electrics Variables
    • <input checked="" disabled="" type="checkbox"> Aircraft Engine Variables
    • <input checked="" disabled="" type="checkbox"> Aircraft Flight Model Variables
    • <input checked="" disabled="" type="checkbox"> Aircraft Fuel Variables
    • <input checked="" disabled="" type="checkbox"> Aircraft Misc. Variables
    • <input checked="" disabled="" type="checkbox"> Aircraft Radio Navigation Variables
    • <input checked="" disabled="" type="checkbox"> Aircraft System Variables
    • <input checked="" disabled="" type="checkbox"> Helicopter Variables

There was no changelog prior to v1.4.1