I forgot to hit Reply to Post. See my message above.
This is a very interesting post. But Iâm still missing some pieces of the puzzle. Iâm trying to understand the relationship between FS2020, SimConnect, WASM, Gauge API, ⊠I have googled like crazy, and have read many posts in this forum. But I miss the big picture. Iâm still not getting it completely. How are things related to each other?
Iâm also confused with some terminology. What does âgauge APIâ really mean. A âgaugeâ is an instrument in a plane, right? Or is there a different context when used for FS2020? If I want to control the FCU of the FBW A32NX, do I need that gauge API?
If I want to talk to the FBW A32NX in FS2020, do I create an executable that connects with SimConnect, can put in requests, and gets answers via some kind of callback function? And if I need this WASM module, do I talk to it through SimConnect, or does my executable needs to have some additional initialization and callback routines for this?
Bottom-line is that I would like to connect my proprietary hardware (based on PIC microconroller and via USB) with the FBW A32NX in FS2020. I have an own piece of software written in C# that is capable of detecting my HW modules (multiple), and is able to send commands (LEDâs, 7-segment displays) and receive data (keypresses, rotaries, âŠ). Letâs call it the âright sideâ of my software. Now I want to develop the âleft sideâ that communicates with FS2020. Next to C#, I also have knowledge of C and C++.
I simply havenât found a total explanation, tutorial, example or demo that shows me the big picture. I would love to see a schematic (donât people make these anymore? ).
I want to contribute as well. Once I have everything up and running, I might start a post to give a full explanation, to bring other newbees like me on the right track.
I hope somebody has the magic key to unlock the knowledge I need!
Ok, Iâll go in chronological (historical) order:
The Gauges API
This is the oldest API, which came with FS2002, itâs a set of C/C++ functions calls, which were initially the only documented API in the sim, was used mainly ( but not only ) airplane developers writing C/C++ gauges, and contains many functions to read simVars ( A: variables ) and âXMLâ vars ( L: variable ), it also contained the âuniversalâ execute_calculator_code, which evaluated an XML expression written using the XML Gauges syntax, which could also be used to read/write variables and/or send events to the sim, like keypresses. This could also be used by developers writing stand-alone .DLL modules that ran in-process to the sim.
The SimConnect API
This is a later API that came with FSX, itâs client-server based so it can be used for both in-process .DLL modules or gauges, but also for external .EXE, not necessarily running on the same PC, because it can also networked. Itâs also supported in P3D, and itâs far more powerful there. It supports .NET and managed code, while the Gauges API itâs C/C++ only.
Since it has been around for a very long time, itâs well documented and still developed (not just by Microsoft, since P3D use it too), itâs by far the most used API. However, it lacks access to things only possible ( L: vars and XML expressions ) with the Gauges API.
WASM
This is the new way to create C/C++ code for MSFS. While Simconnect is still supported, itâs only for external .EXE. C/C++ Gauges and Stand-Alone modules (modules that starts with the sim and ends when the sim exits), that is everything that run âin-processâ, MUST use WASM. However, WASM Gauges/Modules CAN make Simconnect calls as well. The main difference compared to the old FS8/9/FSX Gauges/Modules, is they are heavily sandboxed, meaning they donât really have access to the simulator address space and canât even read any files outside their own package. They can write only on their dedicated area. The main advantage of WASM, is that you can still use C/C++, itâs almost as fast as the true native code, and itâs cross-compatible with Xbox. Also, with WASM ( this is the important bit ), you ALSO have access to the âoldâ Gauges API, the one I listed first.
By putting together all of this, someone needing to access variables and events not accessible directly through Simconnect, has to do the following:
-
Write a Stand-Alone WASM module ( but also a WASM Gauge would work ) that would use the Gauges API to read variables or receive/send events which wouldnât otherwise possible to get through Simconnect.
-
Use the Simconnect API in the WASM module to define custom data areas which can be used to âsend outsideâ these results, to a external Simconnect client that would connect to the WASM module. This is bi-directional too, the external client might ask the WASM module to perform commands/events on its behalf, not just read data from it.
Now, why all these complications ? Wouldnât be easier/better doing everything through WASM ?
No, you canât, because WASM is heavily sandboxed: in addition to not being able to read any files outside its own package, it doesnât even have ANY access to ANY of the Windows APIs ( no Win32, no .NET, nothing, just basic Posix and only in your own folders ) so, even if WASM has a somewhat privileged access to the sim compared to just using Simconnect, it canât do much with it so, youâll realize soon enough you need a ârealâ Windows .EXE for almost everything, especially if you need to interface with some hardware.
Thatâs why the need for bi-directional communication between WASM and another .EXE, using Simconnect âas a transportâ.
Itâs really outside the scope of this post explaining in detail how the Simconnect client data areas and custom events work but, if your goal is JUST interfacing with some hardware, itâs likely easier if you use the Mobiflight module, which has all the basics done and has some specific functions for the A320-NX
@Umberto67 Thanks for this answer, because it clarifies a lot. I have now read almost this complete post, and copied a lot of interesting links from GitHub, BitBucket, âŠ
I was first confused - I thought that you meant to use MobiFlight (which I canât, because at the end, I will not use Arduino), but you mean the MobiFlight WASM module, right? I even found the one that FSUIPC is making. So a lot material to dig into and choose from!
I also agree with your remark that Asobo should provide a default WASM module. But didnât I read somewhere that they are working on some kind of standardization? I donât find the article back unfortunately.
This post is really a great source of information. I have already tried several of the solutions, and itâs a great learning experience. I think that step by step Iâm starting to understand better. Thanks a lot!!!
@davux3 I wanted to look at your fs-gauge-bridge, but what I donât understand is that you seem to put the wasm module in the âPanelâ folder, and not in the âCommunityâ folder? Is there a reason? Can I also put it in the Community folder like the other WASM modules mentioned in this post (example MobiFlight, FSUIPC)
@ImpoliteGem5317 I have successfully used your WASM module and client to experiment with the native A320_Neo. So far the only one that worked! Because of that, it will be a good starting point to look into your code and better understand the internals. I downloaded both the WASM and the client source code, and will have a look at it.
One question I have is why I couldnât use the H-var âH:A320_Neo_MFD_BTN_CSTR_1â. If I use that, nothing happens. Although, if I push the CSTR button with my mouse, the green light goes on, but not if I use the âSet HVARâ menu in your client. I could successfully set other HVars such as all the buttons of the CDU, so âSet HVARâ is definitely working.
@Umberto67 You gave a good explanation of all the variables. But what I miss is the type âBâ. On the native A320_Neo I find for example âB:ELECTRICAL_Battery_1_Toggleâ (the BAT1 button on the OVHD). But what is a B-type, and how can we access it? If I want to toggle the BAT1 switch, how do I do that?
Am I correct to conclude that the WASM module is only used for L-Vars and H-Vars? The other types have to be managed directly with SimConnect? With other words, WASM has to be seen as an âadd-onâ on SimConnect, to allow controlling L-Vars and H-Vars? If I use the FSUIPC client application, it has also an âExecute_Calculator_Codeâ, which I could successfully use with L and H vars, but can I use that for other types as well? I tried with the B-type in it, but my Battery switch is not toggling.
According to the MobiFlight preset list (see https://hubhop.mobiflight.com/) , that hvar is only available in the stable A320. Which version are you using? For the dev version, there are presets A32NX_EFIS_L_CSTR_PUSH and A32NX_EFIS_R_CSTR_PUSH, which use the following calculator code:
(L:A32NX_EFIS_L_OPTION, enum) 1 == if{ 0 } els{ 1 } (>L:A32NX_EFIS_L_OPTION, enum)
(L:A32NX_EFIS_R_OPTION, enum) 1 == if{ 0 } els{ 1 } (>L:A32NX_EFIS_R_OPTION, enum)
i.e. toggle the appropriate lvar.
The WASM module and WAPI interface I provide supports lvars, hvars and calculator code strings (currently up to 255 characters). You should be able to set/activate any type of variable via calculator code, but the WAPI does not provide a mechanism for returning any values from calculator code executed.
If you are using the WAPI to access lvars/hvars, but would also like to read simulator variables (A:vars), then you can either use SimConnect directly in your application, or use the FSUIPC SDK which will provide read/write access to those simvars held in FSUIPC offsets. Alternatively, if using managed code, you could look into using Paul Hentyâs dll client for .Net, which is a higher level c# interface wrapper around the FSUIPC SDK and WAPI.
Calculator code is just what it says. FSUIPC just executes the provided calc. code, so you can use any valid calc code you like, including B-types, A types, K types, etc. If the code is not doing what you think it should, I suspect that it is either invalid or not appropriate for the loaded aircraft.
John
@ImpoliteGem5317 If Iâm not mistaken, I was using the native FS2020 A320_Neo. I think I did something wrong (pretty sure of that ).
I have also the FBW A32NX dev version. I used the Behavior window and pressed CTRL-G when the CSTR button was highlighted allowing me to find the below code that is indeed doing the same as you described (slightly different syntax - your version is shorter, but I understand that both are doing the same).
So I guess that the âBUTTON_CODEâ is to toggle the button and the âINDICATOR_CODEâ is to control the green indicator in the button? Iâm still learning to interpret this RPN notation (still a nightmare because Iâm not used to it ). The SimConnect SDK documentation is very helpful.
From the above screenshot, I have a few questions:
- What does âenumâ exactly do? Why canât I just use (L:A320NX_EFIS_L_OPTION)? Or is the syntax required to have a unit (like meter, feet, âŠ), and because this variable doesnât have a unit, we have to use âenumâ?
- What is â1 sp0 10 (L:A320NX_EFIS_L_OPTION, enum) ==â exactly doing? I read the documentation about sp0, but donât understand. Am I right that this code is enabling/disabling the green indicator light, or is this just a fantasy?
I am no expert in calculator code or gauge programming (first time I have heard of âsp0â!), I just provide the mechanisms for these to be used. You should maybe ask over on the FBW discord channels.
Hi,
You should take a glance on this SDK Chapter: Reverse Polish Notation.
In Reverse Polish Notation (RPN), sp0, sp1, etc are registers where informations can be stored.
In your case, the value 1 is stored in the first register sp0 and the variable L:A320NX_EFIS_L_OPTION is interpreted like a enum (-1, 0, 1, etc) then compared to the value 10 in order to be identical. If yes, the calculation continue.
@LagaffeVFR5476 Thanks for your feedback, but in the meantime, I found my âglitchâ. In the formula, the â10â should be âl0â (character âLâ). And now it makes more sense. sp0 stores value 1 and pops it from the stack, and l0 loads the value from register 0 to the top of the stack. With other words, 1 sp0 l0 does the same as just 1. These kind of weird constructions are the result of the RNP compiler that is used by FBW (at least, that is what I understood from some explanation I got on Discord). Now it makes sense, because I donât compare the EFIS value with 10, but with 1. And this is the CSTR button.
Thank you for sharing this code, it is clear. It certainly works fine in WASM by registering a key event handler, but I went for JavaScript instead. I tried to make this work with a JavaScript listener that I use to intercept key events, but it didnât work. My code is like this:
this.keyListener = RegisterViewListener('JS_LISTENER_KEYEVENT', () => {
Coherent.call('INTERCEPT_KEY_EVENT', 'AP_MASTER', 0);
Coherent.call('INTERCEPT_KEY_EVENT', '0x11000', 0);
Coherent.call('INTERCEPT_KEY_EVENT', '#0x11000', 0);
this.keyListener.on('keyIntercepted', this.handleKeyIntercepted);
});
If you are not familar to JavaScript, this defines a function (hadleKeyIntercepted) that receives all the key events, exactly like the EventHandler you defined in your code. The only difference is that instead of receiving ALL the event, it only receives the ones listed with Coherent.call(âINTERCEPT_KEY_EVENTâ.
It works perfect with AP_MASTER because this is a standard event, but I was unable to get the custom event #0x11000 that is sent through another app.
Any idea?
Thanks.
This is an excellent reply and summary of all the various APIs, thank you very much!
Just to add some âbackground infoâ: WASM stands for âWeb Assemblyâ and is essentially a âweb standardâ (coming from the âbrowser worldâ) which defines a compatible âbyte formatâ which can be interpreted by various browser (and obviously also ânon-browsersâ like Flight Simulator 2020) such as Firefox and Chrome etc.
(As such, it is very much in analogy to âJava Byte Codeâ which can be interpreted and run by any Java Virtual Machine (JVM)).
WASM is not a âMicrosoft inventionâ and for sure it is not Flight Simulator 2020 specific: it is really a âglobal standardâ which allows to exchange âbyte codeâ to be run on various platforms (again, mostly browsers, but also other applications like Flight Simulator 2020 and others).
There exist many âWASM generatorsâ (compilers), specifically also for C/C++, so you can essentially write âweb appsâ in C/C++ and have them run in a browser (or as an addon in Flight Simulator 2020). But as already mentioned those WASM modules are in a tight (hopefully ;)) âsandboxâ (which might be specific to the context which executes the WASM code), so they have only access to a very limited API (which most likely excludes most operating system APIs, for instance).
I also have similar JS_LISTENER_KEYEVENT code running, but have never tried to make it work with custom events.
I believe that Matt and Dominic at WT, were responsible for the introduction of JS_LISTENER_KEYEVENT into MSFS sometime in mid 2021.
Maybe try asking Matt directly on the WT Discord .
I have always found him most helpful, and willing to share technical information w.r.t. MSFS & JS
Yes, I will ask Matt. I already did it in the past and indeed he was very helpful.
For the specific need I had, I found a workaround so there is less urgency but I would like to have the answer.
Thanks
Eric
Boy! What a great find; And explanation too!;Thanks sir! Sure would be nice if someone developed the Lulaâs language the way that that fellow from Germany did for X-Plane. called âFlyWithLuaâ which includes all of the Lvars exposed by X-Plane, and implemented many of them into built-in functions and procedures. I wrote my first code in 40 years with my X-Plane, â LilBlueDonutsâ LilBlueDonuts - Utilities - X-Plane.Org Forum a 2D/VR multi-function AOA HUD and what a joy to learn âFlyWithLuaâ FlyWithLua NG (Next Generation) Edition for X-Plane 11 (Win, Lin, Mac) - Utilities - X-Plane.Org Forum written by (AKA? X-Friezeâ)âŠI wish he would port it over to MSFS, though I understand that MS or Asobo or both are loath to expose their variables. ( seemingly backed up by Randazzoâs (Sp.?)complaint resulting in further delay of the PMDG 737. Iâd love to see that port happen,since Lua is so close to C and C++. Only problem is I could not find an IDE WITH A debugger.
An IDE Like ZeroBrane Studio makes FlyWithLua a joy to use. It does have a debugger, but there were a sufficient number of changes to Lua 5.3, upon which FWL is based, it couldnât debug my code. Granted my code could have been so bad, that it gave upâŠA MSFS port of FlyWithLua could open up a new world to those who want to learn a little code and contribute to the MSFS communityâŠA little help please X-Frieze?!
Sending protective and healing vibes to yâall and your loved ones.
Chas
what is the suggested solution for this? I have a C# app nearly complete (using only SimConnect), except I need to add Lvars ⊠I need a minimal WASM I think and communicate from C# main form
Asobo should provide a default WASM module
Hey guys,
Iâm trying to create an improved version of the in-game checklist for Milviz 310R and trying to remove and install the control lock LVar is giving me problems.
This control lock can be removed with a left click but can only be reinstalled in the EFB tablet.
I think the aircraft is resetting this LVar so my copilot action in the checklist canât stick.
Iâve managed to fix the removal of the control lock by directly copying the left-click event defined in the XML.
But the install control lock is having an issue. The copilot action can install the control lock but itâll only flash one second in the sim and then the control lock is gone and the LVar is reversed back to 0.
Any idea why this is happening and how can I make the value stick?
Regards,
Meo