Jump to content
The simFlight Network Forums

Paul Henty

Members
  • Posts

    1,645
  • Joined

  • Days Won

    74

Posts posted by Paul Henty

  1. Yes, that's how WideFS and WideClient work. You run WideClient on the notebook and any FSUIPC Client software you run (or develop) will see it as FSUIPC and connect.

    The only thing I'm not sure about it the new WASM module to read/write LVars, HVars and run calculator code. @John Dowson will be able to tell you if you can use that on the remote PC. This is separate from the normal FSUIPC protocol and so I don't think it is handled by WideFS7.

    Paul

  2. Hi Robert,

    26 minutes ago, AirPanther said:

    but when I look at the FSUIPC console log, it appears that the offset only gets rewritten to 1 after it changes to 0 (hence the split second change). It is as if all my offsets will only resend if they change even though I call .process() each time.

    That's correct. By default, all offsets will be read on process() except when you have changed the value, in which case the new value is written. They then go back to reading again.

    If you want an offset to only be written (even when the value hasn't changed) you need to mark it as WriteOnly by setting the parameter in the constructor:

    public Offset<BitArray> ControlInhibit = new Offset<BitArray>(0x310A, 1, true); // Write only

    That will make the DLL write the current value every time you call process.

     

    You could also consider putting this offset in a named group so you can process() this at a different time from other offsets you might be using. Here's how you would do that...

    public Offset<BitArray> ControlInhibit = new Offset<BitArray>("inhibit", 0x310A, 1, true);
    FSUIPCConnection.Process("inhibit");  

    ... but it's not required.

    Paul

  3. Quote

    The reason I've chosen just Calculator Code is, If I'm not mistaken, LVars and HVars have to be accompanied by a file associated with a particular aircraft to be directly linked? 

    I believe HVars need a file to be accessed directly by the WASM module. LVars don't need the file. 

    Quote

    instead of the method above where it just blindly tries to send the calculator code and executes it, if the program can?

    I think that's also correct.

    Quote

     does 'Legacy' events just send SimConnect events Via FSUIPC?

    Probably yes. FSUIPC4 and above uses SimConnect in the background for most things. @John Dowson will be able to confirm.

    Paul

  4. Quote

     In the event this process is blowing out my memory, is there another way that isn't as resource intence

    Yes, I've upload a new version for you to try: 3.3.8-beta.

    I've reduced the memory overhead to about 12% of what it was. 

    Remember to tick "Show Pre-Release" in the NuGet package manager to see this beta version.

    Please let me know how it goes.

    Thanks,

    Paul

  5. Thanks,

    Work fine here with your code and those files. The rebuild took 20 seconds to run on my rather old machine.

    Can you try logging the progress output from the RebuildDatabase method? This will tell us how far it's getting/where it's stopping.

    The code will be something like this...

                    if (db.MakeRunwaysFilesExist)
                    {
                        Progress<string> progress = new Progress<string>();
                        progress.ProgressChanged += (o,s) => logger.Info(s);
                        await db.RebuildDatabaseAsync(progress);
                        db.Load();

    I'll look at this again tomorrow morning.

    Paul

  6. Hi Brandon,

    Quote

     how/what is the best way to send this information to the flight simulator. is Calculator code the best way to send not only standard events but also L/Hvars? or as mentioned by John in this thread is the use of Presets the better option.

    Presets are just containers for calculator code, so they end up executing calculator code eventually. They are useful in the FSUIPC front-end, but if you are using code then it's just an extra step. Also the way you call presets from code via FSUIPC is not very efficient.

    If you're using code I would stick to either sending calculator code or using the HVars/LVars directly using the MSFSVariableServices class in my DLL. Which you choose is down to personal preference/convenience/situation. For example, if you're just wanting to read/write a single LVar or activate a single HVar then using the direct method might be easier:

    MSFSVariableServices.HVars["MyHVar"].Set();

    However, if you've found some complicated calculator code on the web, or in a preset, then you might not want to decode what it's doing and replicated the logic yourself. In this instance it would be easier just to copy the code into your application and send it via MSFSVariableServices.ExecuteCalculateCode()

    For aircraft where LVars/HVars are not available you may need to fall back on 'legacy' methods like Events (aka Controls) and Offsets. In this case you need an FSUIPC Connection.

    Events/Controls perform actions in the aircraft (Like HVars). Use the FSUIPCConnection.SendControlToFS() feature.

    To read data use the Offsets. Some offsets can also be written to.

     

    Quote

    As for presets, how are they supposed to be typed into the C# code or is there a txt file that needs to be placed somewhere specific and then references in C#?

    I don't recommend executing presets themselves from code. It's best to just take the underlying calculator code from the preset and execute that. You can copy it directly into your source code. Alternatively, you can have your application read it from your own text file if you want to be able to modify/add calculator code without recompiling your application. 

     

    Quote

    How is this sent to the simulator and could you please give me a C# example of this?

    If you have not already downloaded the MSFSVariableServices example code project please get it from here:

    http://fsuipc.paulhenty.com/#downloads

    It doesn't have an example for calculator code but it will show you how to make a connection and use LVars/Hvars directly.

    In this thread I give an example of executing calculator code as well as using the same HVar directly. There is also a link to a good website where you can find the underlying calculator code for all the presets.

    Feel free to ask further questions. It's a bit confusing if you're coming into this new because there are two systems in use for MSFS: The legacy Events/Controls/Offsets system and the newer LVars/HVars/Calculator code system.

    Paul 

  7. Hi Andy,

    This was a bug on my side. I've just uploaded 3.3.7 to NuGet which fixes this.

    Also note that you'll need to load the database after you rebuild it, or you'll get 0 airports:

    await db.RebuildDatabaseAsync();
    db.Load();
    System.Windows.MessageBox.Show($"MSFS airports build successfully. Total {db.Airports.Count}");
    logger.Info($"MSFS airports build successfully. Total {db.Airports.Count}");

    Paul

  8. You've still got the declarations the wrong way round. 3114 must be declared first, then 3110. Please see the code I pasted in my last reply.

    Quote

    Don't think I need the Disconnect() and DeleteGroup() call,

    You don't need the Disconnect(), but you definitely need to delete the group if you declare (recreate) the offsets each time you send them.

    Quote

    but I can't use the Offsets declared globally (threaded application).  I must declare them at each use (which is strange).

    The DLL is thread-safe and (by default) offsets can be declared on one thread and set/processed on another.

    Quote

     If I don't call Process() the same event is sent over and over, irrespective of what the value of the Event Offsets are (so they don't update)

    If this is the case then either:

    1. Another application is sending these events.

    2. Your application is sending these events from elsewhere in the code. Make sure you haven't declared these offsets somewhere else in another group (or in the default, empty group).

    Also, if you are using a version of my DLL before 3.1.6 you'll need to update as the write-only offsets were buggy before that.

    Paul

     

  9. In the code you've posted you're still declaring the offsets in the wrong order. You need to declare 3114 then 3110.

    I noticed you have swapped the order you set the values, but that doesn't matter. It should be this:

                       Do Until myEventQueue.IsEmpty
                            Dim mySimEventParams As New Offset(Of Integer)("SendControl", &H3114, True)
                            Dim mySimEvent As New Offset(Of Integer)("SendControl", &H3110, True)
                            Dim myEvent As SimEvents
                            myEventQueue.TryDequeue(myEvent)
                            mySimEventParams.SetValue(myEvent.MouseID)
                            mySimEvent.SetValue(myEvent.EventID)
                            SimLogger.Trace("Sending Control {0} with parameter {1}", myEvent.EventID, myEvent.MouseID)
                            FSUIPCConnection.Process("SendControl")
                            FSUIPCConnection.DeleteGroup("SendControl")
                            Thread.Sleep(1000)
                        Loop

    However, this might not solve the problem since your examples are always sending the same parameter value. It would only make a difference on the first ever call. But, you should fix the order in case you ever need to send a different parameter value.

    Other things you might try:

    1. Turn on the Event (control) logging in FSUIPC and output to the console. Check that FSUIPC is receiving what you think the code is sending. And you'll be able to see if anything else is writing that control.
    2. Try with a non-mouse parameter. I think some of the PMDG controls can also take direct values like 0/1 for open/close.

    Paul

  10. Quote
            Private Shared ReadOnly mySimEvent As New Offset(Of Integer)("SendControl", &H3110, True)
            Private Shared ReadOnly mySimParams As New Offset(Of Integer)("SendControl", &H3114, True)

    The order of these offsets matters. FSUIPC sends the control to the sim as soon as you write 3110. So that's before you've written the new parameter - the offsets are written in the order they are declared.

    If you reverse the order of these two lines (declare 3114 first, then 3110) it should work as expected.

    Paul

  11. Hi Tony,

    The new offsets for COM frequencies start at 0x05C4. These are just normal 4-byte 'int' offsets that store the frequency in Hz. To convert to/from the normal MHz value just multiply/divide by 1,000,000.

    These offsets are read/write in P3D, however the Offset Status document for FSUIPC7 (MSFS) says that writing to these offsets does not work yet. It's worth trying though. 

    Also, some third-party aircraft may use their own coding for com frequencies and so these offset won't work at all for those aircraft.

    Paul

  12. Quote

    Is there something I should have done initially to get access to HVars?

    It sounds like the WASM module isn't seeing the HVars. I don't have MSFS so I can't really help with that.

    @John Dowson will be able to help with getting the HVars recognised by the WASM module.

    Hopefully he will see this and reply here. If not, please ask John directly in the MSFS sub-forum: https://forum.simflight.com/forum/183-fsuipc7-msfs/

    Paul

  13. Hi,

    If you go to this site you can look up all the MSFS presets and find out how they work:

    https://hubhop.mobiflight.com/presets/

    (Make sure you select MSFS and not XPlane in the top left).

    If you search for 'AS1000_MFD_RANGE_INC' and expand one of the results you will see the 'code' field. This is the 'calculator code' that get executed when you run the preset:

    (>H:AS1000_MFD_RANGE_INC)

    This is just setting an HVar (not LVar) called AS1000_MFD_RANGE_INC.

    You have two choices to do this with the Client DLL:

    1. Use MSFSVariableServices to execute this exact calculator code:

    string incMFDRange = "(>H:AS1000_MFD_RANGE_INC)";
    MSFSVariableServices.ExecuteCalculatorCode(incMFDRange);

    2. Use MSFSVariableServices to set the HVar directly:

    FsHVar mdfRange = MSFSVariableServices.HVars["AS1000_MFD_RANGE_INC"];
    if (mdfRange != null)
    {
        mdfRange.Set();
    }

     

    When you are looking for controls for an aircraft, be sure to check HVars as well as LVars. Many controls are done with HVars when no values need to be set or read.

    Paul

    • Thanks 1
  14. Version 1.1.2 is now on the website:

    http://fsuipcwebsockets.paulhenty.com/index.html#home

    I've added two 'wildcard' addresses to the dropdown list. (Note that these are not my invention, they are built into Windows. How they work is down to Windows not me.)

    1. * (Handles requests on all physical IP Addresses. Doesn't seem to work with any host names or the 127.0.0.1 loopback address.)
    2. + (Handles requests on all IP Addresses and host names. This creates a secure URL that needs admin permissions.)

    Paul

    • Like 1
  15. As John pointed out the Socket Server runs with any version of FSUIPC from 3 onwards. The only difference is that the 'vars' command will run in a legacy mode for all versions before 7. This is significantly slower than the way 'vars' are handled with MSFS.

    4 hours ago, cknipe said:

    When using WebSocketServer (latest FSUIPC7), if I bind the application to an IP address other than 127.0.0.1 (localhost) - it requires Windows Admin rights to run?  Surely this doesn't seem correct

    Certain URLs and Ports are secured by Windows. To use them, the account the application is running under needs permission.

    You can achieve this is two ways:

    1. By running the application as Admin.

    2. By giving the required permission to the current user. This is done using the following command: (You can execute this in the command window or in code):

    netsh http add urlacl url=[URL TO REGISTER] user=[DOMAIN]\[USER OR GROUP]

    e.g. my PC here is call PJH. My user name is Paul. If I want to use the URL http://PJH:2048/fsuipc I would need this command:

    netsh http add urlacl url=http://PJH:2048/fsuipc/ user=PJH\Paul

    To run this command you need to be running 'as admin'. But once you've given permissions the socket server will be able to work without admin privileges.

    I will add this information to the website.

     

    4 hours ago, cknipe said:

    PS - would be nice to bind to multiple IPs, or listen on any/all IPs.

    A listener can only bind to a one URL. Binding to multiple IPs would require starting multiple listeners on the server side and handling requests from any of them. I don't want to make such a fundamental change to the application at this point. 

    Listening on all IPs might be possible as it looks like the URL can include wildcard symbols. So something like http://*:2048/fsuipc will listen on all IPs.

    At the moment there's no way of typing this in as you need to choose from the dropdown list. I'll look into change this to allow any URL to be typed in. (If the wildcards work).

    This will not get around the Windows security however. You'll still need to grant permissions to the wildcard URL or be running 'as administrator'. 

    Paul 

     

  16. Your C# code shows Keys.D1. Did you paste the wrong line? The log shows you sent the 2 key...

       867593 FSUIPC Control Action: Ctrl=1070, Param=4658
       867593 SendKeyToFS(00030032=[alt+ctl+2], KEYDOWN) ctr=0

    I'm assuming you are calling 

    FSUIPCConnection.SendKeyToFS(Keys.D2, SendModifierKeys.Control | SendModifierKeys.Alt);

    You can see from the log (in bold above) that my DLL has passed on the correct key code to FSUIPC.

    @John DowsonMight be able to tell you why this key combination is working from the keyboard but not through the IPC interface.

    Paul

  17. Quote

    event.offsetmask(0x281C, 1,"UB","Batteryswitch")

    You're using "UB" which is 1 byte. Offset 0x281C is 4 bytes. So you're only testing the first byte. This will always be 0 because the entire 4-byte offset only stores 0 and 1. The actual bit you want to test is in offset 0x281F.

    You can with target that byte:

    event.offsetmask(0x281F, 1,"UB","Batteryswitch")

    or tell LUA read the full 4 bytes from the original offset with "UD" (unsigned double word)

    event.offsetmask(0x281C, 1,"UD","Batteryswitch")

    You don't really need to test the individual bit as only one bit is ever flipped - the entire offset value can only be 0 or 1.

    So you could also use the plain event.offset function like this and test the entire value (0 or 1):

    event.offset(0x281C,"UD","Batteryswitch")

    Paul

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use. Guidelines Privacy Policy We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.