• Which the release of FS2020 we see an explosition of activity on the forun and of course we are very happy to see this. But having all questions about FS2020 in one forum becomes a bit messy. So therefore we would like to ask you all to use the following guidelines when posting your questions:

    • Tag FS2020 specific questions with the MSFS2020 tag.
    • Questions about making 3D assets can be posted in the 3D asset design forum. Either post them in the subforum of the modelling tool you use or in the general forum if they are general.
    • Questions about aircraft design can be posted in the Aircraft design forum
    • Questions about airport design can be posted in the FS2020 airport design forum. Once airport development tools have been updated for FS2020 you can post tool speciifc questions in the subforums of those tools as well of course.
    • Questions about terrain design can be posted in the FS2020 terrain design forum.
    • Questions about SimConnect can be posted in the SimConnect forum.

    Any other question that is not specific to an aspect of development or tool can be posted in the General chat forum.

    By following these guidelines we make sure that the forums remain easy to read for everybody and also that the right people can find your post to answer it.

MSFS Building my first C sharp Simconnect Module (The Journey) using ChatGPT

Messages
809
Country
australia
Okay for years I have developing my own code to bring in fire location data and someone years ago wrote a nice module for it for me, it was a freeware project, but it pulled up an interface module which I was really hoping to have it work as a part of the simconnect system without the interface.

So along comes ChatGPT and suddenly I can see a roadmap to not only re-work and change an old development program a friend wrote for me in Visual Basic and convert it to C sharp that I used for mass scale photoscenery and DEM development, I see an opportunity to learn and have others join in the journey to bring global wildfire data into MSFS and place respective visual effects at those locations with fire and smoke. It looked awesome in FSX/P3D but I want to start from scratch.

The code will be open source, CC attribution, this is a learning process for me and this is day 1.

So my first step was to get ChatGPT to give me a dos command to pull the source file from the NASA website, now the file name format may change over time so there may need to be updates, but maybe I can make that user configurable...

Okay so the CMD under cmd.exe:

Code:
@echo off

rem Check if the file already exists
if exist "c:\MSFS Projects\fires\MODIS_C6_1_Global_24h.csv" (
  echo Overwriting existing file...
  del "c:\MSFS Projects\fires\MODIS_C6_1_Global_24h.csv"
)

rem Download the file
curl -o "c:\MSFS Projects\fires\MODIS_C6_1_Global_24h.csv" https://firms.modaps.eosdis.nasa.gov/data/active_fire/modis-c6.1/csv/MODIS_C6_1_Global_24h.csv

This is attached as DownloadFireCSV.bat.txt <- just rename the .txt to .bat and change your directory of your project inside the text/bat file

Next I asked ChatGPT to re-write it as C sharp code:

Code:
using System;
using System.IO;
using System.Net;

class Program
{
static void Main(string[] args)
{
string filePath = "c:\MSFS Projects\fires\MODIS_C6_1_Global_24h.csv";

    if (File.Exists(filePath))
    {
        Console.WriteLine("Overwriting existing file...");
        File.Delete(filePath);
    }

    using (WebClient webClient = new WebClient())
    {
        webClient.DownloadFile("https://firms.modaps.eosdis.nasa.gov/data/active_fire/modis-c6.1/csv/MODIS_C6_1_Global_24h.csv", filePath);
    }
}
}

Now I'm getting visual basic IDE all set up on my rig so I haven't tested out this code yet but that will be a project for tomorrow.

Steps to Add:
  • Generate MSFS Fire Project Files
  • Generate VFX code for WildFires to Replicate what we have in FSX/P3D
  • Convert from CSV to XML Placement XML file
  • Run CMD based MSFS Scenery Processing Tool
Brainstorming
  • Maybe instead of generating a simconnect module, I could create an applet that resides in the taskbar that downloads the new data each day with a user defined update time
  • Alternately I could make the app run in the cloud and have it upload the master .bgl files to the cloud where users just have to have an applet or simconnect module that pulls in the new BGL every day
Intermediate Data Test:

Preliminary coding to generate a new CSV with only the latitude, longitude, brightness, confidence and bright_t31 values via C sharp

Code:
using System;
using System.IO;
using System.Linq;

class Program
{
static void Main(string[] args)
{
string inputFile = "input.csv";
string outputFile = "output.csv";

    string[] lines = File.ReadAllLines(inputFile);
    string[] newLines = lines.Select(line => line.Split(',')[0] + "," + line.Split(',')[1] + "," + line.Split(',')[2] + "," + line.Split(',')[8] + "," + line.Split(',')[10]).ToArray();

    File.WriteAllLines(outputFile, newLines);
}

}

The goal of the above step is to just test if I can extract the necessary data. Next phase will be to get those values and for each condidence and brightness level break them into small, medium and large WildFireFX placements.

EDIT 2:

Okay I did some refining of the code and gpt inputs and eventually came up with this:

PROMPT: how do i use the HttpClient command in C# to download a file from https://firms.modaps.eosdis.nasa.gov/data/active_fire/modis-c6.1/csv/MODIS_C6_1_Global_24h.csv using 'async' 'task' using net 6.0 and save it to "c:\fires"

RESPONSE:

Here is an example of how you can use the HttpClient command in C# to download a file from https://firms.modaps.eosdis.nasa.gov/data/active_fire/modis-c6.1/csv/MODIS_C6_1_Global_24h.csv using 'async' 'task' using net 6.0 and save it to "c:\fires":

Code:
using System;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        // Create an HttpClient object
        HttpClient client = new HttpClient();

        // Set the download URL
        string url = "https://firms.modaps.eosdis.nasa.gov/data/active_fire/modis-c6.1/csv/MODIS_C6_1_Global_24h.csv";

        // Set the destination path
        string destinationPath = @"c:\fires\MODIS_C6_1_Global_24h.csv";

        // Download the file using the HttpClient
        using (var fileStream = new FileStream(destinationPath, FileMode.Create))
        {
            using (var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
            {
                await response.Content.CopyToAsync(fileStream);
            }
        }

        // Print a message to indicate that the download is complete
        Console.WriteLine("File downloaded successfully to " + destinationPath);
    }
}
In this example, we first create an HttpClient object, which we will use to make the download request. We then set the URL of the file that we want to download, and the destination path where we want to save the file. We then use the HttpClient to download the file using the GetAsync method, passing in the URL and a completion option. We then use the FileStream and FileMode classes to create a new file at the destination path, and use the CopyToAsync method to copy the contents of the response to the file stream. Finally, we print a message to indicate that the download is complete.

Okay so that handled the first part of downloading the files, tested and worked and overwrote any file already downloaded... AWESOME!

Now I did a fair bit of tweaking and trying to build a new class separately to bolt on caused a clash. One thing I learned is I needed to specify C# with the Net 6.0 framework for coding otherwise Visual Basic IDE threw up errors.

So next I asked it to generate the XML code to place the wildfires. Now this isn't yet complete but it's close, I need to get in and make the FX files and also add what to place in the XML code but that will be easy.

PROMPT:

add to this code:
using System;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;

class DownloadWildfireData
{
static async Task Main(string[] args)
{
using (var client = new HttpClient())
{
using (var response = await client.GetAsync("https://firms.modaps.eosdis.nasa.gov/data/active_fire/modis-c6.1/csv/MODIS_C6_1_Global_24h.csv"))
{
response.EnsureSuccessStatusCode();
using (var fileStream = await response.Content.ReadAsStreamAsync())
{
// Make sure the directory exists
Directory.CreateDirectory("c:\\fires");
using (var output = File.Create("c:\\fires\\MODIS_C6_1_Global_24h.csv"))
{
await fileStream.CopyToAsync(output);
}
}
}
}
}
}

the ability to then load the csv file "c:\Fires\MODIS_C6_1_Global_24h.csv" the first line is a comma separated header which outlines: latitude,longitude,brightness,scan,track,acq_date,acq_time,satellite,confidence,version,bright_t31,frp,daynight generate a new xml file and save it in "c:\fires" and name it "objects.xml" in this sample XML code:
<?xml version="1.0"?>
<FSData version="9.0">
<SceneryObject groupIndex="5" lat="LATITUDE" lon="LONGITUDE" alt="0.00000000000000" pitch="0.000000" bank="0.000000" heading="-179.999995" imageComplexity="VERY_SPARSE" altitudeIsAgl="TRUE" snapToGround="TRUE" snapToNormal="FALSE">
</SceneryObject>
</FSData>

replace the word LATITUDE with the latitude value from each line, and LONGITUDE with the longitude value from each line

RESPONSE:

Here is an example of how you can add the ability to load the CSV file, generate a new XML file, and save it in "c:\fires" with the name "objects.xml":

Code:
using System;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using System.Linq;
using System.Xml.Linq;

class DownloadWildfireData
{
static async Task Main(string[] args)
    {
using (var client = new HttpClient())
        {
using (var response = await client.GetAsync("https://firms.modaps.eosdis.nasa.gov/data/active_fire/modis-c6.1/csv/MODIS_C6_1_Global_24h.csv"))
            {
                response.EnsureSuccessStatusCode();
using (var fileStream = await response.Content.ReadAsStreamAsync())
                {
// Make sure the directory exists
Directory.CreateDirectory("c:\\fires");
using (var output = File.Create("c:\\fires\\MODIS_C6_1_Global_24h.csv"))
                    {
 await fileStream.CopyToAsync(output);
                    }
                }
            }
        }

// Load the CSV file
var csvData = File.ReadAllLines("c:\\fires\\MODIS_C6_1_Global_24h.csv").Skip(1).Select(line => line.Split(','));

// Create the XML document
var xmlDoc = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XElement("FSData", new XAttribute("version", "9.0"),
 from data in csvData
select new XElement("SceneryObject",
new XAttribute("groupIndex", "5"),
new XAttribute("lat", data[0]),
new XAttribute("lon", data[1]),
new XAttribute("alt", "0"),
new XAttribute("pitch", "0"),
new XAttribute("bank", "0"),
new XAttribute("heading", "-179.999995"),
new XAttribute("imageComplexity", "VERY_SPARSE"),
new XAttribute("altitudeIsAgl", "TRUE"),
new XAttribute("snapToGround", "TRUE"),
new XAttribute("snapToNormal", "FALSE")
                )
            )
        );

// Save the XML file
xmlDoc.Save("c:\\fires\\objects.xml");
    }
}

Please note that the above code is only an example and might not work correctly. Please also note that you should use better names for your variables and adjust the code to your needs.
 

Attachments

  • DownloadFireCSV.bat.txt
    392 bytes · Views: 2
Last edited:
Top