Demo: LVAR write access for any aircraft control

Thank you for the reminder on event masking!

I forgot they were also there in FS2020. Otherwise I believe there are pros and cons about async/sync and actually having both is much better for the cases you’d need one instead of the other. I don’t have any typical example I’d cite right now but I have no doubt there are some.

thanks, this is one of the most useful threads ever for me. I’m just pulling it together in VS and will have questions for sure … I’m fluent in C#, C C++ so if I can heip anyone let me know …
thanks again

FYI - You can make a project public in DevOps via Project Settings:

It’s all quite straightforward to import a DevOps project into GitHub:
image

It’s good that it was pointed out somewhere around post 80/85 that indeed, the original method that I introduced in the opening post may (most likely will) at some point clash with other developers’ code. For me it’s not that much of an issue, I maintain my private code base and am flexible in renumbering when the need may arise. However, for developers who are looking to use the 0x11000 range for distributed products, this is not the way to go. Thanks for pointing that out more detailed above.

Let’s hope at some stage Asobo will implement a more generic method for us to work with.

Best,
Maurice

1 Like

Is it just me or did anyone else have this stop working with MSFS update to 1.15.7.0?

I am not familiar at all with “WASM development”, so I cannot judge whether this might be related, but there was just an announcement related to WASM modules here:

  • WASM stand alone modules used in some add-ons are no longer working

Thanks for the information! Hopefully, that will fix it.

That was quick:

I’ve only just discovered this, been looking for a way to do this for a while.

Many, many thanks for sharing.

@VFRMau thank you very much for your explanation and your code. I would have never dared to start on something like WASM if you didn’t get me started. Your Github is not ideal but that is maybe even better to get my programming skills up.

@MobiFlight I started with Mobiflight, but because I wasn’t able to get my MIDI encoder knobs to function the way I liked (with vJoy), I started to study your WASM module. I wasn’t able to find out how to connect to your WASM module. Frustrated I gave up and started to study VFRMau’s code. I made my own WASM module and client so I could use my MIDI controller! Very happy but still a bit frustrated I couldn’t use yours. I looked into it again and with new gained knowledge, I figured it out! Thank you very much for putting your code on Github! rtMIDI is a good open source API hint hint wink wink…:wink:

@Umberto67 I agree it would be nice if Asobo would make the sim a little bit more accessible. fingers crossed :slight_smile:

Thanks for your kind words, great hearing that this code is proving useful from time to time.

Best,
Maurice

Yes it is super!

what did you come to understand so you could use it, I’ve not gotten it to work

I am in no way an expert… but it was easier that I thought (after lot of trial and error). This is the core…

void SendToSim(int IDadd, std::string idVar)
{
    hr = SimConnect_MapClientEventToSimEvent(hSimConnect, WASM_EVENT+IDadd, _strdup(idVar.c_str()));
    hr = SimConnect_AddClientEventToNotificationGroup(hSimConnect, GROUP_A, WASM_EVENT + IDadd);
    hr = SimConnect_SetNotificationGroupPriority(hSimConnect, GROUP_A, SIMCONNECT_GROUP_PRIORITY_HIGHEST);
    SimConnect_TransmitClientEvent(hSimConnect, objectID, WASM_EVENT + IDadd, 0, SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
}

Looks familiar, does it not?

this is my functioncall…
SendToSim(26, "mobiflight.AS1000_MFD_ENT_Push");
So IDadd has to be different for every event. and I have not noticed but I think it can mingle with other plug-ins. I used 1 to 50 for my events. I have no other add-ons in my community folder.

You first have to set it up with a Handle and some enums and the connection like…
hr = SUCCEEDED(SimConnect_Open(&hSimConnect, "--- Begin Send Event ---", NULL, 0, 0, 0));
but how this is done can be found everywhere because it is standard simconnect stuff.

So the most important things;
the simconnect_client_event_id has to be something (different for every event) and the
const char " EventName = " has to start with mobiflight. Everything simconnect does not recognize is interpreted by the mobiflight module… translated and send again to simconnect.

If you install mobiflight with the wasm module you can find an event.txt in de module directory in the community directory containing all possibilities added so far. On the website hubhop.mobiflight.com you can maybe find more or in an easier fashion.

This is only the event send part. I still have to find out how to get variables.

Hope this helps.

1 Like

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? :slight_smile: ).

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!

1 Like

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

5 Likes

@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.

1 Like

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.