[SU13] [resolved] [SimConnect] GetInputEvent (managed)

Version: Flighting SU13 - 1.34.10.0

Frequency: Consistently

Severity: Low

Context: External SimConnect Client

Bug description:
Not getting any values except “0” from GetInputEvent. The procedure works, the result comes back, but it always only contains the 0. Documentation is unclear as to how exactly this should be used with managed code. The method requires a DefineID, but the spec does not say, what kind of structure or SimVar has to be be registered to that ID.

Hello @LorbySI

What type of value are you receiving and how do you process it? Can you provide a code snippet please?

DefineID is a duplicate of RequestID, it will be removed from the prototype.

Regards,
Sylvain

Hello Sylvain,

Many thanks for your reply!

Here is my code:
+Request
Sim.Connect.GetInputEvent(DATA_REQUESTS.GET_INPUT_EVENT, hash, DEFINITIONS.INPUT_EVENT_VAR);

I tried binding/registering different structures to DEFINITIONS.INPUT_EVENT_VAR, and I tried to replicate the remark in the spec about the value being a byte Array

+Response

        private void Connect_OnRecvGetInputEvent(SimConnect sender, SIMCONNECT_RECV_GET_INPUT_EVENT data)
        {
                byte[] valArr = BitConverter.GetBytes((uint)data.Value[0]);
                double dVal = BitConverter.ToSingle(valArr, 0);
        }

the uint in the “data.Value” Array is always 0.

My tests were done with the input event for the external power switch cover in the C208:

ELECTRICAL_ExternalPower_1_Cover

I can write to it using “SetInputEvent”, and I can read the value from the BVar no problem, but not with the SimConnect native function.

Edit: I also just tried replacing my DEFINITION with the DATA_REQUEST, but that didn’t make a difference.

Cheers
Oliver

I’m not sure to understand why you convert the Value to an uint and then to a float.

From what I can see in the code, you will receive either a double or a string and the type you want to use will be provided with the hash in the SIMCONNECT_INPUT_EVENT_DESCRIPTOR structure.

In your case, I suspect you are receiving a SIMCONNECT_DATATYPE_FLOAT64, so removing the cast to uint and using ToDouble instead of ToSingle should fix your problem.

Regards,
Sylvain

Because that is what it is, I cannot cast it to anything else, that would lead to an “invalid cast” exception.

In the SDK doc, when I go to the SimConnect Reference, “SimConnect_GetInputEvent” there is a link to

(…/Structures_And_Enumerations/SIMCONNECT_RECV_GET_INPUT_EVENT.htm)

This link is broken, the file does not exist.

What does exist instead is
“SIMCONNECT_RECV_INPUT_EVENT_VALUE.htm”
which describes the SIMCONNECT_RECV_GET_INPUT_EVENT structure.

And there it says

NOTE : In C#, Value is an object array containing one uint value. This value must be converted to a byte array before being converted to the correct type.

That is technologically correct, I can see that structure (array of uint) in VS Debug Mode. But that doesn’t change the fact that all it contains is always and in all circumstances - 0.
Maybe I am not understanding what kind of value an Input Event should have? I thought that it is the same as the BVar has = the value that I set with “SetInputEvent”. Or am I going wrong with that assumption?

Hello @LorbySI

My bad, I’m not very familiar with C#.

So as I said, you will receive either a double or a 256 chars string.
The SimConnect class offers a RegisterStruct method that you can use for both types of data.
First, create the 2 structures:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
struct GetInputEventDouble
{
    public double value;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
struct GetInputEventString
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    public string value;
}

That’s where the DefineID comes in, it’s used to identify the type of data and cast the received value in the appropriate type.
You just need to define an enum with both types:

public enum InputEventType
{
    DOUBLE,
    STRING
}

and now use the RegisterStruct method to register both types with their corresponding type id:

m_oSimConnect.RegisterStruct<SIMCONNECT_RECV_GET_INPUT_EVENT, GetInputEventDouble>(InputEventType.DOUBLE);
m_oSimConnect.RegisterStruct<SIMCONNECT_RECV_GET_INPUT_EVENT, GetInputEventString>(InputEventType.STRING);

Now for a given InputEvent, you just need to use the appropriate DefineID when calling GetInputEvent, depending on the type you received in SIMCONNECT_INPUT_EVENT_DESCRIPTOR when calling EnumerateInputEvents, and you will be able to cast data.Value[0] into the corresponding structure.

As both types are known, we are going to streamline this a bit, register the types on our side and make a bit more obvious that GetInputEvent is expecting a type.

Regards,
Sylvain

Hello Sylvain,

thank you for your effort, it is working now.

Btw. the same “Note” as I quoted above is also in the description of the SubscribeInputEvent method.

##### Remarks

This struct will be the response to a call to [`SimConnect_SubscribeInputEvent`](../InputEvents/SimConnect_SubscribeInputEvent.htm). Note that in C#, `Value` is an object array containing one `uint` value. This value must be converted to a byte array before being converted to the correct type.

IMHO this should be corrected too, as it is very misleading.

But all this leads me to another question: when I use EnumerateInputEventParams to query the data type of the Input Event, most of the data that I get back is empty. In some cases it says “;FLOAT64” but not for all events that should have this type:

IEV Param: <ELECTRICAL_Avionics_Bus_Tie_Cover><>
IEV Param: <ELECTRICAL_ExternalPower_1_Cover><>
IEV Param: <DEICE_Windshield_1><>
IEV Param: <DEICE_Airframe_1><;FLOAT64>
IEV Param: <DEICE_Pitot_1><;FLOAT64>

Incidentally, what would be the use case for a “String” Input Event?

Hello @LorbySI

To query the data type of the InputEvent value, you want to use EnumerateInputEvents, not EnumerateInputEventParams.

EnumerateInputEventParams will give the list of parameters you are expected to pass when calling SetInputEvent
Those that are empty are basically toggle events where no parameters are expected.

We have no existing case of Asobo InputEvents based on string value or parameter at the moment, everything goes through doubles.
But in theory this is possible if your IE uses a string as value for example so the SimConnect functions reflect that possibility.

Regards,
Sylvain

Hello Sylvain,

thank you for your patience!

Best Regards
Oliver

1 Like