[RESOLVED] reading and displaying weather data through c# console application

Discuss on the SimConnect SDK can be used by programmers to write add-on components for Prepar3D
Locked
mer
Posts: 25
Joined: Fri Aug 31, 2018 10:52 am

[RESOLVED] reading and displaying weather data through c# console application

Post by mer »

Hello,

I'm trying to extract weather data through a c# console application; the c# equivalent of the example below:
https://www.prepar3d.com/SDKv4/sdk/simc ... ation.html

As a first step i thought i could convert a window-form-based c# application into a console-based one and tried to do so for the ManagedData Request application

But I can't read the data using the code below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using LockheedMartin.Prepar3D.SimConnect;
using System.Runtime.InteropServices;
using System.Threading;

namespace WeatherParser_SimConnect
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
struct Struct1
{
// this is how you declare a fixed size string
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public String title;
public double latitude;
public double longitude;
public double altitude;

};
class Program
{
enum DEFINITIONS
{
Struct1,
}

enum DATA_REQUESTS
{
REQUEST_1,
};
SimConnect simconnect = null;
const int WM_USER_SIMCONNECT = 0x0402;//??
IntPtr Handle;
int quit = 0;


static void Main(string[] args)
{
Program p = new Program();
p.connect();
p.addToData();
// p.close();
}
void simconnect_OnRecvSimobjectDataBytype(SimConnect sender, SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE data)
{

switch ((DATA_REQUESTS)data.dwRequestID)
{
case DATA_REQUESTS.REQUEST_1:
Struct1 s1 = (Struct1)data.dwData[0];

Console.WriteLine("Title: " + s1.title);
Console.WriteLine("Lat: " + s1.latitude);
Console.WriteLine("Lon: " + s1.longitude);
Console.WriteLine("Alt: " + s1.altitude);
break;

default:
Console.WriteLine("Unknown request ID: " + data.dwRequestID);
break;
}
}


private void addToData()
{
// define a data structure

try {


simconnect.OnRecvOpen += new SimConnect.RecvOpenEventHandler(simconnect_OnRecvOpen);
simconnect.OnRecvQuit += new SimConnect.RecvQuitEventHandler(simconnect_OnRecvQuit);

// define a data structure
simconnect.AddToDataDefinition(DEFINITIONS.Struct1, "Title", null, SIMCONNECT_DATATYPE.STRING256, 0.0f, SimConnect.SIMCONNECT_UNUSED);
simconnect.AddToDataDefinition(DEFINITIONS.Struct1, "Plane Latitude", "degrees", SIMCONNECT_DATATYPE.FLOAT64, 0.0f, SimConnect.SIMCONNECT_UNUSED);
simconnect.AddToDataDefinition(DEFINITIONS.Struct1, "Plane Longitude", "degrees", SIMCONNECT_DATATYPE.FLOAT64, 0.0f, SimConnect.SIMCONNECT_UNUSED);
simconnect.AddToDataDefinition(DEFINITIONS.Struct1, "Plane Altitude", "feet", SIMCONNECT_DATATYPE.FLOAT64, 0.0f, SimConnect.SIMCONNECT_UNUSED);

// IMPORTANT: register it with the simconnect managed wrapper marshaller
// if you skip this step, you will only receive a uint in the .dwData field.
simconnect.RegisterDataDefineStruct<Struct1>(DEFINITIONS.Struct1);

simconnect.OnRecvSimobjectDataBytype += new SimConnect.RecvSimobjectDataBytypeEventHandler(simconnect_OnRecvSimobjectDataBytype);

simconnect.RequestDataOnSimObjectType(DATA_REQUESTS.REQUEST_1, DEFINITIONS.Struct1, 0, SIMCONNECT_SIMOBJECT_TYPE.USER);

Thread.Sleep(1);

}
catch (COMException ex)
{
Console.WriteLine(ex.Message);
}

}

void simconnect_OnRecvOpen(SimConnect sender, SIMCONNECT_RECV_OPEN data)
{
Console.WriteLine("Connected to Prepar3D");
}

// The case where the user closes Prepar3D
void simconnect_OnRecvQuit(SimConnect sender, SIMCONNECT_RECV data)
{
Console.WriteLine("Prepar3D has exited");
if (simconnect != null)
{
// Dispose serves the same purpose as SimConnect_Close()
simconnect.Dispose();
simconnect = null;
Console.WriteLine("Connection closed");
}
}

private void connect()
{
try
{
simconnect = new SimConnect("Managed Data Request", this.Handle, WM_USER_SIMCONNECT, null, 0);
}
catch (COMException ex)
{
Console.WriteLine("A connection to the SimConnect server could not be established");
}
}

private void close()
{
if (simconnect != null)
{
// Dispose serves the same purpose as SimConnect_Close()
simconnect.Dispose();
simconnect = null;
Console.WriteLine("Connection closed");
}
}
}
}

Could anyone guide me on how I need to go about this?

Thank you
mer
Posts: 25
Joined: Fri Aug 31, 2018 10:52 am

Re: reading and displaying weather data through c# console application

Post by mer »

I was able to display the message by adding simconnect.receiveMessage after the simconnect.RequestDataOnSimObjectType(DATA_REQUESTS.REQUEST_1, DEFINITIONS.Struct1, 0, SIMCONNECT_SIMOBJECT_TYPE.USER);

Can someone help me with the weather data ?
obinder
Posts: 145
Joined: Sun Jun 08, 2014 9:43 am

Re: reading and displaying weather data through c# console application

Post by obinder »

I was able to display the message by adding simconnect.receiveMessage after the simconnect.RequestDataOnSimObjectType
No, that is not how it is done. I suggest you re-read the managed code samples in the Learning Center and SDK.
You are establishing a hook to the Windows messaging system, but you are not querying it. This is the most important part of your program:
protected override void DefWndProc(ref Message m)
{
if (m.Msg == WM_USER_SIMCONNECT)
{
if (simconnect != null)
{
simconnect.ReceiveMessage();
}
}
else
{
base.DefWndProc(ref m);
}
}
Learning Center -> SDK -> SimConnectAPI -> Managed SimConnect Projects

Best regards
obinder
Posts: 145
Joined: Sun Jun 08, 2014 9:43 am

Re: reading and displaying weather data through c# console application

Post by obinder »

mer wrote: Sun Sep 09, 2018 1:54 pm Can someone help me with the weather data ?
Console C# application doesn't really work. To achieve a console-like appearance, make a Forms app, use FormBorderStyle "None" and minimize it in code. Use a Timer or similar to connect to the sim, so the sequence of what is being started first (app or sim) doesn't matter so much. Make sure that the simulation is running (and the user is not in a dialog currently), then use one of the multiple ways to get weather data.
Directly with SimConnect by using WeatherRequestInterpolatedObservation, WeatherRequestObservationAtNearestStation, WeatherRequestObservationAtStation.
LearningCenter -> SDK -> SimConnect -> References -> "World Functions" -> "Weather Specific Function Name"

or by querying various Simulation variables:
AMBIENT DENSITY, AMBIENT TEMPERATURE, AMBIENT PRESSURE, AMBIENT WIND VELOCITY, AMBIENT WIND DIRECTION, AMBIENT WIND X, AMBIENT WIND Y, AMBIENT WIND Z, STRUCT AMBIENT WIND, AMBIENT PRECIP STATE, AMBIENT PRECIP RATE, AIRCRAFT WIND X, AIRCRAFT WIND Y, AIRCRAFT WIND Z, BAROMETER PRESSURE, SEA LEVEL PRESSURE, TOTAL AIR TEMPERATURE, AMBIENT IN CLOUD, AMBIENT VISIBILITY, STANDARD ATM TEMPERATURE
LearningCenter -> SDK -> References -> Variables -> Simulation Variables -> Aircraft Environment Variables

Best regards
mer
Posts: 25
Joined: Fri Aug 31, 2018 10:52 am

Re: reading and displaying weather data through c# console application

Post by mer »

Thank you very much
Locked