/// <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); }
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); } }
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)"); }
//[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); }
private int SendRequest(SimConnectVariable request, int frequency) { return(SimConnectHelper.SimConnectHelper.GetSimVar(request, frequency)); // If FetchLatestValue = true; Auto-update }
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); }