BaseInstruments.js

 

The BaseInstruments.js file defines the BaseInstruments class which has multiple functions designed as the base for getting your HTML/JS/CSS instruments working within Microsoft Flight Simulator. This file will be inserted into the gauge context automatically for you when you create a gauge and you will need to extend on the BaseInstruments class for your gauges to work correctly. For example, take the following short JS code:

class My_Gauge extends BaseInstrument {
    constructor() {
        super();
    }
    get templateID() {
        return "AS1000_SpeedBackup";
    }
    connectedCallback() {
        super.connectedCallback();
        const electricityElement = document.getElementById("Electricity");
        const divElement = document.createElement("div");
        divElement.setAttribute('id', 'HelloWorld');
        divElement.innerHTML = "Hello World!";
        electricityElement.appendChild(divElement);
    }    
}
registerInstrument('simple-glasscockpit-sample', My_Gauge);

 

We won't be listing all the available methods here, but the following table shows the most important ones that you will be using:

 

Method Description
templateID() Returns the template ID matching the ID you set in your HTML file (see here for details: JavaScript)
connectedCallback() This method is called after the DOM is rendered. This is a good place to look for an HTML element with JavaScript.
Init() This method is called when the gauge is first instantiated, although the DOM might not be ready.
parseXMLConfig() This method is used to parse the (optional) panel.xml, which is used to add additional functionality to your gauges.
Update() This method is essentially an infinite loop that can be used to refresh your glasscockpit.
urlConfig.index() This method gets the index of the glasscockpit that has been set in the panel.cfg file.

 

 

templateID()

This method is mandatory to redefine, has no parameters, and should return the ID of the gauge as defined in your HTML entry-point file. It will tell Microsoft Flight Simulator the HTML template to add into the DOM. For example:

get templateID() {
    return "MyGauge_Template";
}

 

 

connectedCallback()

This method is called when the DOM is properly mounted, and it has no parameters. This is a safe place to start dealing with your HTML elements because you can be sure they already exist. For example:

connectedCallback() {
    super.connectedCallback();
    const electricityElement = document.getElementById("Electricity");
    const divElement = document.createElement("div");
    divElement.setAttribute('id', 'HelloWorld');
    divElement.innerHTML = "Hello World!";
    electricityElement.appendChild(divElement);
}

 

 

Init()

This method is called automatically when all Instruments are loaded and SimVars are ready to use (which will set BaseInstruments.allInstrumentsLoaded to true). Note however, that does not mean that glasscockpits have actually been added to the sim and that the DOM is being rendered, so dealing with HTML elements at this moment can be dangerous because you don't know precisely in which state things are in. If you need HTML actions, it's safer to use connectedCallback().  Also note that if you redefine Init() in your code, you should use super to still call the Init() in BaseInstrument.

By calling super.Init(), the parseXMLConfig() method is called. For example:

init() {
    this._initialized = false;
    this.checkMasterInitIntervalId = null;
    this.flightPlanInitStarted = false;
    this.setCurrentWaypointNumber(0, this.isMaster);
    this.setCurrentSequenceIndex(0, this.isMaster);
    if (this.isMaster) {
        SimVar.SetSimVarValue("L:MAP_SHOWN_FLIGHTPLAN_INDEX", "number", this.MAIN_FLIGHTPLAN_ID);
        SimVar.SetSimVarValue("L:VFR_MAP_SHOWN_FLIGHTPLAN_INDEX", "number", this.MAIN_FLIGHTPLAN_ID);
        this.ddi.addEventListener("Reboot", () => {
            if (this.isMaster && this.initialized) {
                this._initialized = false;
                this.flightPlanInitStarted = false;
            }
        });
    }
}

 

 

parseXMLConfig()

Each aircraft can define its own panel.xml file (placed in the same folder as the panel.cfg) and then define their own custom elements within that to hold fixed values or perform logical operations using the Panel XML Logic Elements. This is especially useful as an easy way to modify the capabilities of a glasscockpit display depending on the aircraft that is using it (among other things). For example, say you want to display radar altitude in your glasscockpit, but not every aircraft is equipped with the appropriate probe. In this case, you could define a <RadarAltitude> element in the XML file and set it to True/False then retrieve this value in the JavaScript, adapting the gauge logic dynamically to enable/disable this instrument when required. The following example code shows hows this could be achieved:

parseXMLConfig() {
    super.parseXMLConfig();
    if (this.instrumentXmlConfig) {
        const radarAltitude = this.instrumentXmlConfig.getElementsByTagName("RadarAltitude");
        if (radarAltitude.length > 0) {
            this.radarAltitudeElement.style.display = radarAltitude ? "block", "none";
        }
    }
}

 

 

Update()

This is a loop that you can use to refresh your glasscockpit every frame that the simulation is running, for example, based on SimVars:

update() {
    const volts1 = SimVar.GetSimVarValue("ELECTRICAL GENALT BUS VOLTAGE:4", msfssdk.SimVarValueType.Volts);
    const volts2 = SimVar.GetSimVarValue("ELECTRICAL GENALT BUS VOLTAGE:5", msfssdk.SimVarValueType.Volts);
    const load1 = SimVar.GetSimVarValue("ELECTRICAL GENALT LOAD:4", msfssdk.SimVarValueType.Percent);
    const load2 = SimVar.GetSimVarValue("ELECTRICAL GENALT LOAD:5", msfssdk.SimVarValueType.Percent);
    const isOn = SimVar.GetSimVarValue("GENERAL ENG MASTER ALTERNATOR:4", msfssdk.SimVarValueType.Bool) === 1
        || SimVar.GetSimVarValue("GENERAL ENG MASTER ALTERNATOR:5", msfssdk.SimVarValueType.Bool) === 1;
    this.loadPct.set(isOn ? Math.max(load1, load2) : 0);
    this.volts.set(isOn ? Math.max(volts1, volts2) : 0);
    this.isAvailable.set(isOn);
}

 

 

urlConfig.index()

It is possible for you to render the same glasscockpit multiple times within a single virtual cockpit, for example having two G1000 - one PFD and the other MFD. This means that you will want to dynamically change certain behaviours with the way each one works or what information each one displays, based on which one it is. This is achieved by frist editing the  file to add an index value to each glasscockpit definition, something like this:

[VCockpit01]
size_mm            = 400,512
pixel_size         = 400,512
texture            = SpeedDisplay_1
background_color   = 42,42,40
htmlgauge00        = NavSystems/AS1000_BackupDisplay/Speed/AS1000_SpeedBackup.html?Index=1,0,0,400,512
[VCockpit02]
size_mm            = 400,512
pixel_size         = 400,512
texture            = SpeedDisplay_2
background_color   = 42,42,40
htmlgauge00        = NavSystems/AS1000_BackupDisplay/Speed/AS1000_SpeedBackup.html?Index=2,0,0,400,512

 

This index can then be checked using the urlConfig.index() method, for example:

if (this.instrument.urlConfig.index)
    bingMapId += "_GPS" + this.instrument.urlConfig.index;