• Which the release of FS2020 we see an explosition of activity on the forun and of course we are very happy to see this. But having all questions about FS2020 in one forum becomes a bit messy. So therefore we would like to ask you all to use the following guidelines when posting your questions:

    • Tag FS2020 specific questions with the MSFS2020 tag.
    • Questions about making 3D assets can be posted in the 3D asset design forum. Either post them in the subforum of the modelling tool you use or in the general forum if they are general.
    • Questions about aircraft design can be posted in the Aircraft design forum
    • Questions about airport design can be posted in the FS2020 airport design forum. Once airport development tools have been updated for FS2020 you can post tool speciifc questions in the subforums of those tools as well of course.
    • Questions about terrain design can be posted in the FS2020 terrain design forum.
    • Questions about SimConnect can be posted in the SimConnect forum.

    Any other question that is not specific to an aspect of development or tool can be posted in the General chat forum.

    By following these guidelines we make sure that the forums remain easy to read for everybody and also that the right people can find your post to answer it.

MSFS html gauge tutorial and samples

Messages
646
Country
australia
Yahallo

I've spent the last 2 months in the shed hammering away at html gauges. I've managed to make a couple of gauges, a radio and a fuel level for my aircraft. After much cursing and swearing I think I have a slight understanding of how to make a gauge. I have made this simple tutorial to help share the knowledge.

Let me just start by saying html is hard. There is a lot of code you need to write just to get something to work in MSFS. I also recommend developing in a web browser instead of MSFS at least for the layout stage of your gauge. MSFS is a real pain in the butt to work within. The tutorial includes examples of gauges that will run in a browser as well as detailing the changes you need to make to convert that gauge to run in MSFS.

Disclaimer: I am not an expert in html, js or css. These examples may not be the most efficient or perfect way to create gauges for MSFS. But they work. They are what I was able to figure out from the last 2 months of repeated head banging against the wall.

Final disclaimer: Please do not ask me to figure out why your gauge is not running. All I can say is carefully check your syntax (including capitalisation) and any changes you make. Like I said, making html gauge is not easy.

This picture shows the sample gauges in operation. As you can see they are very simple, I didn't want anything too complex so you could just focus on the core layout of the gauges. The one on the left is made using SVG elements and you can rotate and translate the yellow rectangle with the elevator and aileron controls. The one on the right is easier to code and uses DIV elements. SVG elements are more complex but necessary if you want to create graphics and glass cockpits. DIV elements are easier and are great for simple text displays (such as radio displays).

At the bottom of the picture on the left you can see the radio gauge I wrote and on the right is the default Aera which is being substituted by the sample SVG gauge. Using the Aera substition allows people using the tutorial to quickly see the gauge in operation without needing to build your own aircraft and create dummy panels.

htmlgaugetutorial.jpg
 

Attachments

  • AntsTutorialGauge.zip
    109.9 KB · Views: 376
Messages
4
Country
unitedstates
Thanks for doing this Anthony. I don't know if MSFS has changed since you posted this but I'm struggling to follow along with the 'LET'S START' section. You suggest copying the generic 'hmtl_ui' folder from the base MSFS install but I can't find this folder in the location you describe? Maybe I'm missing something simple but I'd appreciate any help you could offer to help me understand this.

Thanks.
 
Messages
646
Country
australia
Thanks for doing this Anthony. I don't know if MSFS has changed since you posted this but I'm struggling to follow along with the 'LET'S START' section. You suggest copying the generic 'hmtl_ui' folder from the base MSFS install but I can't find this folder in the location you describe? Maybe I'm missing something simple but I'd appreciate any help you could offer to help me understand this.

Thanks.
The install location of MSFS is only something you know. I can only tell you where it is if you install MSFS through the MS Store without changing the default location. If you need more information you should provide some more information. I cannot provide detailed answers to vague questions.
 
Messages
4
Country
unitedstates
Yeah, I guess that question was a bit vague. My installation is from the Microsoft store and in the default location but it's OK now. I haven't found exactly what you describe but I think I've found what I need.

Thanks for your reply.
 
Messages
11
Country
belgium
Hey @Anthony31,

Thanks for this tutorial! It made it all a lot clearer to me. Would you know prehaps, how you can define where such a gauge is getting its electrical power from?
I have coded an EDM900, but I couldn't figure out yet how to tell to MSFS: "Hey, this is an EDM900 and it is connected to that power source (e.g. an internal alternator)". I found it for some general stuff (in the systems.cfg). But how do I tell that there should be also an EDM900 in the systems list (it's not a default circuit as far as I know).

Thanks in advance!
 
Messages
646
Country
australia
Hey @Anthony31,

Thanks for this tutorial! It made it all a lot clearer to me. Would you know prehaps, how you can define where such a gauge is getting its electrical power from?
I have coded an EDM900, but I couldn't figure out yet how to tell to MSFS: "Hey, this is an EDM900 and it is connected to that power source (e.g. an internal alternator)". I found it for some general stuff (in the systems.cfg). But how do I tell that there should be also an EDM900 in the systems list (it's not a default circuit as far as I know).

Thanks in advance!
Hi Hans

I'm not at my work computer at the moment but from memory you can use CIRCUIT_XML:n where n is any number (start at 1 and go up depending on how many circuits you need). I think some of the default airplanes use CIRCUIT_XML to supply power to the GPS units (or some other gauges) and so I just copied that and use circuit_xml as a generic power circuit(s). Those aircraft then link the circuit (which may be different depending on the aircraft) through the panel.xml file but I couldn't really figure out how to link that in the javascript so I just directly read the status of the A: var for the circuit within the javascript. You can also switch the circuit on/off in javascript.

I'll edit this comment later to add some more detail as the default gauges use an electricity function in the javascript to check if the power is on/off and the html then uses that function to show/hide the display.

Here's the edits and some examples:

For the systems.cfg

circuit.12 = Type:CIRCUIT_AUDIO #Connections:bus.2# Power:10, 12, 11.5# Name:Audio ; Audio 15W
circuit.13 = Type:CIRCUIT_AUTOPILOT #Connections:bus.2# Power:10, 12, 11.5# Name:Autopilot ; Autopilot 15W
circuit.14 = Type:CIRCUIT_XML:1 #Connections:bus.2# Power:10, 12, 11.5# Name:Radios
circuit.15 = Type:CIRCUIT_XML #Connections:bus.2# Power:10, 15, 11.5# Name:Aera_Tablet

This is in the css:
Code:
#Electricity {
  width: 100%;
  height: 100%; }
  #Electricity[state=off] {
    display: none; }

This is in the html. Wrapping your display elements in div id="Electricity" seems to control them:
Code:
<script type="text/html" id="Ants_ICA22_Radio">
    <div id="Mainframe">
        <div id="Electricity" state="off">  
       
            Put all your div id elements in here
      </div>
    </div>
</script>


This is in the js and these two functions check if power is available:

Code:
    updateA22Electricity() {
        let powerOn = this.isA22ElectricityAvailable();
        if (this.electricity) {
            if (powerOn)
                this.electricity.setAttribute("state", "on");
            else
                this.electricity.setAttribute("state", "off");
        }
        return powerOn;
    }
    isA22ElectricityAvailable() {
        var _circuitOn = SimVar.GetSimVarValue("CIRCUIT ON:14", "Bool");
        var _mainVolts = SimVar.GetSimVarValue("ELECTRICAL MAIN BUS VOLTAGE", "volts");
        if ( _circuitOn && _mainVolts > 5 ) { return 1; } else { return 0; }
        return 0;
    }

These are all based off default gauge code so you can refer back to some of the default gauges if you like. It's been months since I wrote these and I think I've forgotten most of the reasoning behind them. But as you can see I am directly reading the CIRCUIT ON:14 simvar to determine if the circuit is on and if there is any main bus volts (the circuit might be on but there needs to be enough power too).

Finally here is some js code showing how to switch a circuit off if it is on. In this case it's turning off a light on circuit 11 if the radio is off.

Code:
if ( SimVar.GetSimVarValue("CIRCUIT ON:11", "Bool") ) { SimVar.SetSimVarValue("K:ELECTRICAL_CIRCUIT_TOGGLE", "number", 11); }
 
Last edited:
Messages
145
Country
unitedkingdom
great stuff Anthony (as always).

For the actual display I do something very similar in my gauges except I haven't found it necessary to use predefined identifiers like Electricity and this.electricity which I guess means in Asobo code somewhere there's a this.electricity = document.getElementById("Electricity"). If I have something like <div id="b21_radio"> with the HTML/CSS/JS structure being very similar to yours, the power on/off of the gauge is just via this.radio_el = document.getElementById("b21_radio")[/ICODE} and [ICODE]this.radio_el.style.display="block" and this.radio_el.style.display="none". Your isA22ElectricityAvailable() function is the genius part and IMHO you don't need to then fall back to the Asobo electricity or show/hide code.

I'd like to add a probably more useful hint (than my stuff just above) of my own, which is update functions are typically called from within the BaseInstrument Update function which means they get called (typically) 18 times per second. As a general programming style it's quite easy to have the gauge only make CSS updates when necessary, rather than setting className or other element attributes (like "state") on every cycle which causes the renderer to have to go through all the CSS rules on every update cycle to see if the display should change. Clearly for power on/off the actual update is relatively infrequent, and the technique I use on all my gauges is to have variables ending in _prev which record the 'previous' state of some variables to the CSS update will only occur if there is a change. In this example you'd have a this.powerOn and this.powerOn_prev and the CSS controlling block would be:
Code:
let powerOn = this.isA22ElectricityAvailable();
if (this.powerOn_prev==null || this.powerOn_prev != powerOn) {
                this.electricity.setAttribute("state", powerOn ? "on" : "off"); // but I'd actually use this.b21_radio_el.style.display = powerOn  ? "block" : "none"; (same either way really)
}
this.powerOn_prev = powerOn
 
Last edited:
Top