Master branch updated to set the Data Type to String (if not already defined) when Units are declared as a String (Units are set to NULL for Strings earlier in the code - patch just checks for that).
default:
if (string.IsNullOrEmpty(unit))
simConnect.RegisterDataDefineStruct<SimVarString>(simReq.DefID);
else
simConnect.RegisterDataDefineStruct<double>(simReq.DefID); // We'll presume default values being requested are numeric
break;
If you used the Git Clone or Visual Studio download options from GitHub, you can use the Pull feature of Git in Visual Studio to pull down the latest changes, so you don’t need to apply the changes locally yourself
Not experience with the Github pull but it seems easy.
Meanwhile here my code with you help.
foreach (var toConnect in simConnectProperties)
{
values = toConnect.Value.Split(new char[] { ',' });
if (values[1] != "string")
{
sim.AddToDataDefinition((DUMMYENUM)toConnect.Key, values[0], values[1], SIMCONNECT_DATATYPE.FLOAT64, 0.0f, SimConnect.SIMCONNECT_UNUSED);
sim.RegisterDataDefineStruct<double>((DUMMYENUM)toConnect.Key);
}
else
{
// neste momento apanha as strings porque são contveridas em null
sim.AddToDataDefinition((DUMMYENUM)toConnect.Key, values[0], null, SIMCONNECT_DATATYPE.STRINGV, 0.0f, SimConnect.SIMCONNECT_UNUSED);
sim.RegisterDataDefineStruct<string256Struct>((DUMMYENUM)toConnect.Key);
}
}
here I receive the string
case (8):
Var8 = ((double)data.dwData[0]).ToString();
break;
case (9):
Var9 = ((string256Struct)data.dwData[0]).strVal;
break;
That looks fine if you’re only going to fetch numeric and string values.
Just wrote a Unit Test to fetch every SimVar and discovered around 10% (90 SimVars) fail, mainly because they expect a non-standard result to be registered, such as a structure.
Yes, you are right! As I am beginning to work with the variables I will find those gaps now or later. 90 is too much but the structures will be a few, I think. Interesting your tests!
Hi DragonIard,
it would help me a lot, if you could kindly provide a small simple programme which just uses your SimConnectHandler_Test and these three methods:
ConnectUseLocalServerConfig_Test
RequestSimVar_Test_Once
Disconnect_Test
Thanks in advance!
Hi DragonIard,
thanks for answering!
No hurry at all. I continued to dive into Visual Studio and have already found out the implicit “Test”-category of Visual Studio. I am getting closer to not just understand your code but also will be able to get parts of it running in own mini test programmes
I’ve just updated the code with a breaking change. I’ve renamed the SimConnectHandler to SimConnectHelper, as it makes more sense when writing your own code to use it as follows:
SimConnectHelper.Connect();
I’ve also added the initial code to disable AI for submitted values, although this isn’t fully tested yet as I’m simply too busy for the next few days.
For info, there are 3 projects in the solution:
SimConnectHelper - This is the actual code you will reference/use in your own projects
SimConnectHandler_Demo - A simple form that uses the SimConnectHelper as an example
SimConnectHandler_Tests - A collection of Unit Tests intended to automate various test scenarios using the SimConnectHelper
As I suspect you’ve realised, you wouldn’t call the methods you mentioned as they are Unit Tests, used for automated testing of the main project (SimConnectHelper).
To use the project yourself in your own code, you would need a copy of the SimConnectHelper project (the other 2 projects are just for testing and demo’ing the main project).
Within your own project, create a reference to the SimConnectHelper project (so your code can find and use it), then all you need to do is call the relevant methods of the helper in your code.
You don’t need to create an instance of the helper - it’s always available.
So, to connect to MSFS 2020 running on the same PC, you would just write in your own code:
SimConnectHelper.Connect();
There’s a lot you can do with the helper, so please read the full tutorial (above), review the documentation (I will be adding more to the project Wiki), follow the examples (in both the Demo and Unit Test projects) and experiment yourself, I often find learning is best achieved by experimenting.
Hello Dragonlaird
Im using VS2019 C#.
I think I need the last little kick to understand how your SimconnecHelper is working.
I have added SimconnectHelper to my proj. and added “using SimConnectHelper;”
and “using SimConnectHelper.Common;” to my MainWindow.cs file - so far so good…
Now… can you support me with the function() that set my public variable “public double planeHeading;” to the heading of my user plane in FS2020 ??
Apologies for not responding sooner, I’ve been away, with no access to Internet. I’m currently at work but I’ll look into this as soon as I finish tonight
I’ve not tested this as I’m having to download a 40Gb update - but the code compiles without error:
using SimConnectHelper.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace SimConnectHandler_Demo
{
public class FARyoufly_Sample
{
private IDictionary latestResults = new Dictionary();
public void Main()
{
SimConnectHelper.SimConnectHelper.SimError += SimConnect_Error;
SimConnectHelper.SimConnectHelper.SimConnected += SimConnect_Connection;
SimConnectHelper.SimConnectHelper.SimData += SimConnect_DataReceived;
SimConnectHelper.SimConnectHelper.Connect();
var simVarName = "GPS GROUND TRUE HEADING"; // Or "HEADING INDICATOR", "PLANE HEADING DEGREES GYRO", "INDUCTOR COMPASS HEADING REF", "PLANE HEADING DEGREES MAGNETIC", "PLANE HEADING DEGREES TRUE"
var variable = new SimConnectVariable
{
Name = simVarName,
Unit = "radians"
};
var requestID = SimConnectHelper.SimConnectHelper.GetSimVar(variable, 50); // Ask SimConnect to send the value every 50ms
for (var i = 0; i < 100; i++)
{
// Latest value of the SimVar can be retrieved by calling method below
var planeHeading = GetSimVarValue(simVarName);
// If value hasn't been returned yet, it will default to zero
Console.WriteLine($"{i:000}: Heading: {planeHeading}");
Thread.Sleep(10); // Wait for 10ms before checking again
}
}
private double GetSimVarValue(string simVarName)
{
if (latestResults.ContainsKey(simVarName))
return (double)latestResults[simVarName].Value;
return 0;
}
private void SimConnect_DataReceived(object sender, SimConnectVariableValue e)
{
lock (latestResults)
{
if (latestResults.ContainsKey(e.Request.Name))
latestResults[e.Request.Name] = e;
else
latestResults.Add(e.Request.Name, e);
}
}
private void SimConnect_Error(object sender, ExternalException e)
{
throw new NotImplementedException();
}
private void SimConnect_Connection(object sender, bool e)
{
if (e)
{
// SimConnect has connected successfully
}
else
{
// SimConnect has disconnected
}
}
}
}
No, variable is the SimVar Request you want to fetch the value for, it can be re-used after you’ve submitted the request, MSFS will remember which SimVars you have asked for.
No, in fact really, you don’t need to create any variables, as the Dictionary:
latestResults
Contains the values for any SimVar you request (assuming the values you request are all of type double - most are).
So for every SimVar you want to request, set up “variable” as shown in the code above, then call:
The request will be processed by MSFS and the value returned (every 50ms, or whatever speed you want the value to update).
You can then access the latest returned values anywhere in your code by calling:
myValue = GetSimVarValue(simVarName);
Where simVarName is a string containing the name of the SimVar you originally requested (e.g. “GPS GROUND TRUE HEADING”) and myValue will contain the latest value received from MSFS.
A simple way to use this would be to create a method that runs at startup and sends all your SimVar requests as soon as your app loads, then in your code where you need the value (e.g. the heading), you would simply write something like:
var heading = GetSimVarValue("GPS GROUND TRUE HEADING");
Great - thanks…
I played a little with you suggested code…
But my Code comes up with a error… I have installed requested NuGet packed.
In this part it comes with an error… IDictionary does not contain a definition for “ContainsKey”.
if (latestResults.ContainsKey(simVarName))
return (double)latestResults[simVarName].Value;
I noob but learning fast
Appreciate your help
Frank