/// <summary>
        /// Allows cancelling of a previously requested variable, if it is no-longer needed
        /// </summary>
        /// <param name="request">SimVar Request to cancel</param>
        public static bool CancelRequest(SimConnectVariable request)
        {
            WriteLog("Start CancelRequest(SimConnectVariable)");
            var result = false;

            if (simConnect != null && IsConnected && Requests.Any(x => x.Value.Name == request.Name && x.Value.Unit == request.Unit))
            {
                lock (Requests)
                {
                    try
                    {
                        var submittedRequest = Requests.First(x => x.Value.Name == request.Name && x.Value.Unit == request.Unit);
                        var requestId        = submittedRequest.Key;
                        if (requestId > -1)
                        {
                            //simConnect.ClearDataDefinition((SIMVARDEFINITION)requestId);
                            simConnect.ClearClientDataDefinition((SIMVARDEFINITION)requestId);
                            Requests.Remove(requestId);
                            RemoveTimer(requestId);
                            result = true;
                        }
                    }
                    catch (Exception ex)
                    {
                        WriteLog(string.Format("Cancellation Error: {0}", ex.Message), EventLogEntryType.Error);
                    }
                }
            }
            WriteLog("End CancelRequest(SimConnectVariable)");
            return(result);
        }
        internal static SimVarRequest AddRequest(SimConnectVariable request)
        {
            SimVarRequest simReq;

            lock (Requests)
            {
                if (Requests.Any(x => x.Value.Name.Equals(request.Name, StringComparison.InvariantCultureIgnoreCase) &&
                                 x.Value.Unit.Equals(request.Unit, StringComparison.InvariantCultureIgnoreCase)))
                {
                    // Re-use a previously requested variable for retransmission to SimConnect
                    var reqId = GetRequestId(request);
                    simReq = new SimVarRequest
                    {
                        ID      = reqId,
                        Request = request
                    };
                }
                else
                {
                    // Fetch the values suitable for transmission to SimConnect
                    simReq = new SimVarRequest
                    {
                        ID      = RequestID++,
                        Request = request
                    };
                    // New SimVar requested - add it to our list
                    Requests.Add((int)simReq.ReqID, simReq.Request);
                }
            }
            return(simReq);
        }
        public void RequestSimVar_Test_Once()
        {
            result = null;
            SimConnectHandler.SimError     += SimConnect_Error;
            SimConnectHandler.SimConnected += SimConnect_Connection;
            SimConnectHandler.SimData      += SimConnect_DataReceived;
            SimConnectHandler.Connect();
            var variable = new SimConnectVariable
            {
                Name = "AMBIENT WIND VELOCITY",
                Unit = "knots"
            };
            var requestID = SimConnectHandler.RegisterSimVar(variable, SimConnectUpdateFrequency.Once);

            // Wait up to 5 seconds for MSFS to return the requested value
            DateTime endTime = DateTime.Now.AddSeconds(5);

            while (result == null && DateTime.Now < endTime)
            {
                Thread.Sleep(100);
            }
            SimConnectHandler.CancelRequest(variable);
            SimConnectHandler.Disconnect();
            Assert.IsNotNull(result);
        }
 private static int GetRequestId(SimConnectVariable request)
 {
     WriteLog("Start GetRequestId(SimConnectVariable);\r\nEnd GetRequestId(SimConnectVariable)");
     return(Requests.Any(x =>
                         x.Value.Name.Equals(request.Name, StringComparison.InvariantCultureIgnoreCase) &&
                         x.Value.Unit.Equals(request.Unit, StringComparison.InvariantCultureIgnoreCase)) ?
            Requests.FirstOrDefault(x =>
                                    x.Value.Name.Equals(request.Name, StringComparison.InvariantCultureIgnoreCase) &&
                                    x.Value.Unit.Equals(request.Unit, StringComparison.InvariantCultureIgnoreCase)).Key
         : -1);
 }
Exemplo n.º 5
0
        private void dgvButton_Click(object sender, DataGridViewCellEventArgs e)
        {
            var reqId = (int?)dgVariables.Rows[e.RowIndex].Cells["ReqID"].Value;

            if (e.ColumnIndex == dgVariables.Columns["SimVarUpdate"].Index)
            {
                // User wants to refresh the displayed value
                if (reqId > -1)
                {
                    SimConnectHelper.SimConnectHelper.GetSimVar((int)reqId);
                }
                else
                {
                    var isReadOnly = ((DataGridViewCheckBoxCell)dgVariables.Rows[e.RowIndex].Cells["VarIsReadOnly"]).Value
                                     == ((DataGridViewCheckBoxCell)dgVariables.Rows[e.RowIndex].Cells["VarIsReadOnly"]).TrueValue;
                    var simVarName             = (string)dgVariables.Rows[e.RowIndex].Cells["SimVarName"].Value;
                    var simVarUnit             = (string)dgVariables.Rows[e.RowIndex].Cells["SimVarUnit"].Value;
                    var frequency              = dgVariables.Rows[e.RowIndex].Cells["SimVarFreq"].Value;
                    SimConnectVariable request = new SimConnectVariable
                    {
                        Name = simVarName,
                        Unit = simVarUnit
                    };
                    if (isReadOnly)
                    {
                        dgVariables.Rows[e.RowIndex].Cells["ReqID"].Value = SendRequest(request, int.Parse(frequency.ToString()));
                    }
                    else
                    {
                        var value = dgVariables.Rows[e.RowIndex].Cells["SimVarValue"].Value;
                        SendValue(new SimConnectVariableValue
                        {
                            Request = request,
                            Value   = value
                        }, cbDisableAI.Checked);
                    }
                }
            }
            if (e.ColumnIndex == dgVariables.Columns["SimVarDelete"].Index)
            {
                var simVarName             = (string)dgVariables.Rows[e.RowIndex].Cells["SimVarName"].Value;
                var simVarUnit             = (string)dgVariables.Rows[e.RowIndex].Cells["SimVarUnit"].Value;
                SimConnectVariable request = new SimConnectVariable
                {
                    Name = simVarName,
                    Unit = simVarUnit
                };
                SimConnectHelper.SimConnectHelper.CancelRequest(request);
                dgVariables.Rows.RemoveAt(e.RowIndex);
            }
        }
Exemplo n.º 6
0
 private void RequestAllSimVars()
 {
     foreach (DataGridViewRow row in dgVariables.Rows)
     {
         var simVarName = row.Cells["SimVarName"].Value?.ToString();
         var simVarUnit = row.Cells["SimVarUnit"].Value?.ToString();
         var request    = new SimConnectVariable
         {
             Name = simVarName,
             Unit = simVarUnit
         };
         SimConnectHelper.SimConnectHelper.GetSimVar(request);
     }
 }
        /// <summary>
        /// Request an update for a specific SimVar request (used for GetSimVar(frequency = SIMCONNECT_PERIOD.NEVER))
        /// </summary>
        /// <param name="requestID">Variable definition requested via GetSimVar</param>
        public static void GetSimVar(SimConnectVariable request)
        {
            WriteLog("Start GetSimVar(SimConnectVariable)");
            var reqId = GetRequestId(request);

            if (reqId > -1)
            {
                GetSimVar(reqId);
            }
            else
            {
                RegisterSimVar(request, SimConnectUpdateFrequency.Never);
            }
            WriteLog("End GetSimVar(SimConnectVariable)");
        }
Exemplo n.º 8
0
        //[TestMethod]
        public void GetEverySimVar()
        {
            List <SimConnectVariable> failures = new List <SimConnectVariable>();
            const int frequency = (int)SimConnectUpdateFrequency.Once;
            const int resultDelayCheckMilliseconds = 5;
            const int maxWaitForResultMilliseconds = 1000;

            SimConnectHelper.SimConnectHelper.Disconnect();
            SimConnectHelper.SimConnectHelper.SimError     += SimConnect_Error;
            SimConnectHelper.SimConnectHelper.SimConnected += SimConnect_Connection;
            SimConnectHelper.SimConnectHelper.SimData      += SimConnect_DataReceived;
            SimConnectHelper.SimConnectHelper.Connect();
            foreach (var simVarDefinition in SimVarUnits.DefaultUnits)
            {
                SimConnectVariable request = new SimConnectVariable {
                    Name = simVarDefinition.Value.Name, Unit = simVarDefinition.Value.DefaultUnit
                };
                int requestId = SimConnectHelper.SimConnectHelper.GetSimVar(request, frequency);
                // -1 is the default value for a request that could not be sent - usually because SimConnect is not connected to MSFS 2020
                Assert.AreNotEqual(-1, requestId);
                // Ask SimConnect to fetch the latest value
                result = null;
                SimConnectHelper.SimConnectHelper.GetSimVar(requestId);
                var endWaitTime = DateTime.Now.AddMilliseconds(maxWaitForResultMilliseconds);
                while (result == null && endWaitTime > DateTime.Now)
                {
                    Thread.Sleep(resultDelayCheckMilliseconds); // Wait to receive the value
                }
                if (result == null)
                {
                    failures.Add(request);
                }
                SimConnectHelper.SimConnectHelper.CancelRequest(request);
            }
            SimConnectHelper.SimConnectHelper.Disconnect();
            foreach (var request in failures)
            {
                Debug.WriteLine(string.Format("{0} ({1})", request.Name, request.Unit));
            }
            Assert.AreEqual(0, failures.Count());
        }
        /// <summary>
        /// Request a SimVar value using a custom-defined frequency
        /// </summary>
        /// <param name="request">SimVar to request</param>
        /// <param name="frequencyInMs">Frequency (in ms)</param>
        /// <returns></returns>
        public static int GetSimVar(SimConnectVariable request, int frequencyInMs)
        {
            WriteLog("Start GetSimVar(SimConnectVariable, int)");
            var simReq    = AddRequest(request);
            var requestId = (int)simReq.ReqID;

            if (frequencyInMs > (int)SIMCONNECT_PERIOD.SECOND)
            {
                if (requestId > -1)
                {
                    GetSimVar(requestId, (SimConnectUpdateFrequency)frequencyInMs);
                }
            }
            else
            {
                if (requestId > -1)
                {
                    GetSimVar(requestId, (SimConnectUpdateFrequency)Enum.Parse(typeof(SimConnectUpdateFrequency), frequencyInMs.ToString()));
                }
            }
            WriteLog("End GetSimVar(SimConnectVariable, int)");
            return(requestId);
        }
Exemplo n.º 10
0
 private int SendRequest(SimConnectVariable request, int frequency)
 {
     return(SimConnectHelper.SimConnectHelper.GetSimVar(request, frequency)); // If FetchLatestValue = true; Auto-update
 }
Exemplo n.º 11
0
        private void pbSendRequest_Click(object sender, EventArgs e)
        {
            var  selectedItem     = (KeyValuePair <string, SimVarDefinition>)cmbVariable.SelectedItem;
            var  index            = cmbIndex.SelectedItem?.ToString();
            var  simVarName       = selectedItem.Key + (string.IsNullOrEmpty(index) ? "" : (":" + index));
            var  simVarDefinition = selectedItem.Value;
            bool bCanSendRequest  = FindRowBySimVarName(simVarName) == null;

            if (bCanSendRequest)
            {
                var value = "";
                int reqId = -1;
                //var isReadOnly = simVarDefinition.ReadOnly;
                //if (!simVarDefinition.ReadOnly)
                value = txtSimVarValue.Text;
                var frequency = cmbFrequency.SelectedItem;
                if (frequency.ToString() == "Milliseconds")
                {
                    frequency = (int)txtMilliseconds.Value;
                }
                int rowIdx = dgVariables.Rows.Add(new object[]
                {
                    0,                            // RecID
                    simVarName,                   // SimVar
                    simVarDefinition.DefaultUnit, // Units
                    frequency.ToString(),         // Frequency
                    value,                        // Value
                    simVarDefinition.ReadOnly     // ReadOnly
                });
                dgVariables.Rows[rowIdx].Cells["ReqID"].ReadOnly         = true;
                dgVariables.Rows[rowIdx].Cells["SimVarName"].ReadOnly    = true;
                dgVariables.Rows[rowIdx].Cells["SimVarUnit"].ReadOnly    = true;
                dgVariables.Rows[rowIdx].Cells["SimVarFreq"].ReadOnly    = true;
                dgVariables.Rows[rowIdx].Cells["VarIsReadOnly"].ReadOnly = true;
                dgVariables.Rows[rowIdx].Cells["SimVarValue"].ReadOnly   = false;
                //ReqID
                //SimVarName
                //SimVarUnit
                //SimVarValue
                //VarIsReadOnly
                SimConnectVariable variableRequest = new SimConnectVariable
                {
                    Name = simVarName,
                    Unit = simVarDefinition.DefaultUnit
                };
                if (string.IsNullOrEmpty(value))
                {
                    // Send Request - then update ReqID cell with returned request ID
                    reqId = SendRequest(variableRequest, (int)Enum.Parse(typeof(SimConnectUpdateFrequency), frequency.ToString()));
                }
                else
                {
                    SimConnectVariableValue variableValue = new SimConnectVariableValue
                    {
                        Request = variableRequest,
                        Value   = value
                    };
                    reqId = SendValue(variableValue, cbDisableAI.Checked);
                }
                dgVariables.Rows[rowIdx].Cells["ReqID"].Value = reqId;
            }
        }
        /// <summary>
        /// Request a SimVariable from SimConnect, optionally start capturing values
        /// </summary>
        /// <param name="request">SimVar to fetch from SimConnect</param>
        /// <param name="frequency">How frequently should SimConnect provide an updated value?</param>
        /// <returns>A unique ID for the submitted request. Use this to request the next value via FetchValueUpdate</returns>
        public static int RegisterSimVar(SimConnectVariable request, SimConnectUpdateFrequency frequency = SimConnectUpdateFrequency.Never)
        {
            WriteLog("Start GetSimVar(SimConnectVariable, SimConnectUpdateFrequency)");
            if (IsConnected)
            {
                var unit = request.Unit;
                if (unit?.IndexOf("string") > -1)
                {
                    unit = null; // String values don't actually have a unit
                }
                SimVarRequest simReq = AddRequest(request);
                // Submit the SimVar request to SimConnect
                try
                {
                    var    simVarName = request.Name;
                    double index      = 0;
                    if (simVarName.IndexOf(':') > -1)
                    {
                        index      = double.Parse(simVarName.Substring(simVarName.IndexOf(':') + 1));
                        simVarName = simVarName.Substring(0, simVarName.IndexOf(':'));
                    }
                    simConnect.AddToDataDefinition(simReq.DefID, simVarName, unit, simReq.SimType, 0.0f, SimConnect.SIMCONNECT_UNUSED);
                    // Tell SimConnect what type of value we are expecting to be returned
                    switch (simReq.DataType?.FullName)
                    {
                    case "System.UInt16":
                    case "System.UInt32":
                    case "System.UInt64":
                        simConnect.RegisterDataDefineStruct <uint>(simReq.DefID);
                        break;

                    case "System.Int16":
                    case "System.Int32":
                        simConnect.RegisterDataDefineStruct <int>(simReq.DefID);
                        break;

                    case "System.Boolean":
                        simConnect.RegisterDataDefineStruct <bool>(simReq.DefID);
                        break;

                    case "System.Byte":
                        simConnect.RegisterDataDefineStruct <byte>(simReq.DefID);
                        break;

                    case "System.String":
                        simConnect.RegisterDataDefineStruct <SimVarString>(simReq.DefID);
                        break;

                    case "System.Object":
                        simConnect.RegisterDataDefineStruct <object>(simReq.DefID);    // This will likely fail as variants don't transform well
                        break;

                    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 (frequency != SimConnectUpdateFrequency.Never)
                    {
                        GetSimVar(simReq.ID, DefaultUpdateFrequency); // Request value to be sent back immediately, will auto-update using pre-defined frequency
                    }
                }
                catch (Exception ex)
                {
                    WriteLog(string.Format("SimConnect Error: {0}\r\nEnd GetSimVar(SimConnectVariable, SimConnectUpdateFrequency)", ex.Message), EventLogEntryType.Error);
                    SimConnect_OnRecvException(simConnect, new SIMCONNECT_RECV_EXCEPTION {
                        dwException = (uint)ex.HResult
                    });
                    return(-1);
                }
                WriteLog("End GetSimVar(SimConnectVariable, SimConnectUpdateFrequency)");
                return(simReq.ID);
            }
            WriteLog("SimVar Not Found\r\nEnd GetSimVar(SimConnectVariable, SimConnectUpdateFrequency)", EventLogEntryType.Warning);
            return(-1);
        }