Firefly Posted September 14, 2020 Report Posted September 14, 2020 What is the best way to make a browser web page interface with FSUIPC? So that we can easily design our own panels with buttons and information from the aircraft/simulator using HTML/CSS/Javascript? How could that be done? It seems like it should utilize websockets since that provides two-way instant communication and the WebSocket API is supported by any modern browser. But FSUIPC doesn't have a websocket server in-built I presume... Plain requests via the HTTP protocol could be an alternative but would only be optimal for button presses... I'm aware of WideFS button capabilities - it would be some similar to that but just done in the browser instead so that it will have many more options for layout and information. Seems with today's browsers it should be doable performance-wise and therefore an obvious feature to have.
John Dowson Posted September 14, 2020 Report Posted September 14, 2020 1 hour ago, Firefly said: What is the best way to make a browser web page interface with FSUIPC? There is no web browser interface to FSUIPC as far as I'm aware. Please check the SDK for the available interfaces. I guess, for example, you could write a java plug-in that runs in the browser and communicates to FSUIPC via one of the Java SDKs. Or one of the other SDKs (e.g. python) if that is supported by the browser. There are no plans to add a HTTP or websockets interface directly to FSUIPC.
John Dowson Posted September 14, 2020 Report Posted September 14, 2020 Actually, I'll put this on my list to investigate at some point. i.e add a http (or maybe websockets) interface to FSUIPC. However, I don't expect to have time to look into this for quite some time. Any such interface would only expose reading and writing to the offset data area, as is supported by the current SDK. John
John Dowson Posted September 15, 2020 Report Posted September 15, 2020 I've been thinking about this a bit and it should actually be pretty simple to implement, so I'll add it to my 'to be implemented' list. However, with FSUIPC7 for MSFS being the priority at the moment, it will take some time before I can get around to looking at this in detail. I will implement as a plug-in dll, so I can add extra features not available in the SDK, such as a direct 'control/event' interface, not via offsets. Also, it should be reasonably straightforward to implement as a separate process, using one of the provided SDKs. All that is needed is to add an embedded http/websockets server, and then exposed the FSUIPC SDK functions as endpoints. The most developed/used SDK at the moment seems to be Paul Henty's .net client. Maybe @Paul Henty has already considered this? John
Paul Henty Posted September 15, 2020 Report Posted September 15, 2020 Hi John, Yes I've thought about it as I've seen some other requests for this in past but I didn't have the time for new project. As you say, a small application that runs in the system tray that provides an http interface should be fairly straight forward. As well as the basic offset read/write I could also expose the helper classes in the DLL like accessing weather and AI traffic. I guess the main advantage of a separate program is that it'll work with all version of FSUIPC/Flight Sims. I'll investigate his week as I don't think it'll be too big a project and I'll report back. Paul
John Dowson Posted September 15, 2020 Report Posted September 15, 2020 29 minutes ago, Paul Henty said: I'll investigate his week as I don't think it'll be too big a project and I'll report back. That's great, thanks Paul. John
Firefly Posted September 15, 2020 Author Report Posted September 15, 2020 Guys, that's great to hear! I really think this could be very useful and open up for a lot of possibilities - as there are a lot of people who know how to work with the web technologies but don't how to use lower level languages, do compiling and all that stuff. But simple web APIs is what is tying systems together nowadays. Looking forward to see what you can come up with!
Paul Henty Posted September 17, 2020 Report Posted September 17, 2020 I have a proof of concept working. It uses HTTP requests. I can't see any advantage in using WebSockets as FSUIPC itself does not have duplex communication. It's only one-way poll & response from client to FSUIPC. Just to make sure I'm on the right track, and check if this this would be useful, I've posted some javascript below that I've used for testing. This runs directly in a browser, completely client-side. It talks to the HTTP server program that is located on the flight sim PC (or can be on a different PC if connecting to the flight sim over WideFS). The URL consists of the IP of the server and port number (setup in the server program) followed by /fsuipc/ and then the type of request you are making. e.g. to request offset data it might look like this: http://localhost:2048/fsuipc/offsets You'll make an AJAX POST request to this URL, passing a JSON stringified array of offset requests (details in the code below). Then you'll get back another JSON string containing the values which you can turn into a Javascript object to use. Here's the Javascript for reading three offsets: var fsuipcURL = "http://localhost:2048/fsuipc/"; function btnReadOffsetsClick(e) { // make a request to the sever to read offset data // First setup a data structure containing the offset requests // This is an array of offset objects. Each object contains: // name: used to identify the value when the response comes back (can be anything) // address: Hexadecimal address of the offset // type: the type of data in the offset. Must be: // 'int' (signed integer) // 'uint' (unsigned integer) // 'string' // 'float' // size: The size of the offset in bytes offsets = [ { name: 'avionicsMaster', address: '2E80', type: 'uint', size: 4}, { name: 'heading', address: '0580', type: 'uint', size: 4}, { name: 'aircraftName', address: '3D00', type: 'string', size: 256 }, ]; // create the URL var offsetsURL = fsuipcURL + "offsets"; // create a new AJAX request object var xhttp = new XMLHttpRequest(); // setup a function to execute when the data is returned xhttp.onreadystatechange = function () { showOffsetData(this); }; // make the request xhttp.open("POST", offsetsURL, true); xhttp.send(JSON.stringify(offsets)); } function showOffsetData(e) { // clear error display document.getElementById('fsuipcReadOffsets').innerHTML = ''; var displayHTML = ""; if (e.readyState >= 3 && e.status == 200) { // decode the JSON response var response = JSON.parse(e.responseText); if (response.Success) { var data = response.Data; // display each offset value on the page document.getElementById('aircraftName').innerText = data['aircraftName']; document.getElementById('avionicsMaster').innerText = data['avionicsMaster'] > 0 ? 'ON' : 'OFF'; // convert heading from FS units to degrees var headingDegrees = data['heading'] * 360 / (65536 * 65536); document.getElementById('headingTrue').innerText = headingDegrees.toFixed(2); } else { displayHTML = "Request failed with error code: " + response.ErrorCode + " " + response.ErrorMessage; } } else { displayHTML = "Error communicating with FSUIPC Web Services. "; } // set any error HTML into the div document.getElementById('fsuipcReadOffsets').innerHTML = displayHTML; } This is the result: Do you think this would work? Thanks, Paul
Firefly Posted September 18, 2020 Author Report Posted September 18, 2020 Hi Paul, You're fast! This is great - it's exactly what I had in mind for HTTP communication. It can certainly work in a lot of scenarios - I'm just thinking that in case you for example wanted to do a gauge you would want very frequent updates, at least every 50-100 ms, and in that case there would be quite a bit of overhead in constantly opening/closing the HTTP connection and passing headers. At least theoretically that would be a concern... so that's why I was thinking of websockets. I was imagining that you could subscribe to a set of offsets which would then continually be sent back to the client at a given interval (maybe even user desired interval?). Either all the subscribed offsets could be returned, or even better, only those that have changed since last time. I understand that FSUIPC in itself is stateless - poll and response - so this would of course require a running websocket server with some logic in it. But due to the overhead of HTTP I believe it would perform substantially better to have that websocket server continually poll FSUIPC internally than doing the polling over the HTTP protocol? Or is there something I'm missing? Thanks, Allan
Paul Henty Posted September 18, 2020 Report Posted September 18, 2020 Hi Allan, Thanks for the feedback. I can see that the WebSockets model would be a better solution. I'll look into it... Paul
Paul Henty Posted September 19, 2020 Report Posted September 19, 2020 I've got WebSockets working. Here's a quick video of real time updates every 100ms. https://youtu.be/E6RR94O8nfs This is the JavaScript for this page: var fsuipcURL = "ws://127.0.0.1:2048/fsuipc"; var ws; function btnConnectClick(e) { if (!ws) { // create a new WebSocket using the URL with the 'fsuipc' protocol. ws = new WebSocket(fsuipcURL, "fsuipc"); ws.onopen = function () { alert("Socket Open..."); }; ws.onmessage = function (evt) { // Find out which request was responded to and process it var response = JSON.parse(evt.data); switch (response.name) { case 'info': showInfo(response); break; case 'offsetsTest': showOffsetData(response); break; } }; ws.onclose = function () { // websocket is closed. alert("Connection is closed..."); ws = null; }; } } function btnInfoClick(e) { // make a request to the sever for info. request = { request: 'info', name: 'info' }; if (ws) { ws.send(JSON.stringify(request)); } } function btnReadOffsetsClick(e) { // make a request to the sever to read offset data // First setup a data structure containing the offset requests // This contains an array of ofset objects. Each object contains: // name: used to identify the value when the response comes back (can be anything) // address: Hexadecimal address of the offset // type: the type of data in the offset. Must be: // 'int' (signed integer) // 'uint' (unsigned integer) // 'string' // 'float' // size: The size of the offset in bytes request = { request: 'offsets.read', // Tell the server to read offsets name: 'offsetsTest', // An ID so we can match the response interval: 100, // Send every 100ms - specfiy 0 for read once (no repeat). offsets: [ { name: 'altitude', address: '0570', type: 'int', size: 8 }, { name: 'avionicsMaster', address: '2E80', type: 'uint', size: 4 }, { name: 'heading', address: '0580', type: 'uint', size: 4 }, { name: 'aircraftName', address: '3D00', type: 'string', size: 256 }, ] }; if (ws) { ws.send(JSON.stringify(request)); } } function showInfo(response) { if (response.success) { var data = response.data; // Create a table to display the data displayHTML = '<table>'; // enumerate each returned data item and add as a row to the table for (var propertyName in data) { displayHTML += '<tr>'; displayHTML += '<td>' + propertyName + '</td><td>' + data[propertyName] + '</td>'; displayHTML += '</tr>'; } displayHTML += "</table>"; } else { displayHTML = "Request failed with error code: " + response.errorCode + " " + response.errorMessage; } document.getElementById('fsuipcInfo').innerHTML = displayHTML; } function showOffsetData(response) { // clear error display document.getElementById('fsuipcReadOffsets').innerHTML = ''; var displayHTML = ""; if (response.success) { var data = response.data; // display each offset value on the page document.getElementById('aircraftName').innerText = data['aircraftName']; document.getElementById('avionicsMaster').innerText = data['avionicsMaster'] > 0 ? 'ON' : 'OFF'; // convert heading from FS units to degrees var headingDegrees = data['heading'] * 360 / (65536 * 65536); document.getElementById('headingTrue').innerText = headingDegrees.toFixed(0); // convert altitude metres to feet var altitudeFeet = data['altitude'] / (65535 * 65535) * 3.28084; document.getElementById('altitude').innerText = altitudeFeet.toFixed(0); } else { displayHTML = "Request failed with error code: " + response.errorCode + " " + response.errorMessage; } // set any error HTML into the div document.getElementById('fsuipcReadOffsets').innerHTML = displayHTML; } Is that more like what you had in mind? If so, I'll get it to a stable version with offset read and write so you can test it. Let me know if you have any other comments or suggestions. Paul 2
Firefly Posted September 19, 2020 Author Report Posted September 19, 2020 Thanks! Really appreciate your efforts.
Firefly Posted September 20, 2020 Author Report Posted September 20, 2020 I have reviewed the code now - it looks terrific! Good to see you have the "name" ID in there so that we can match the response in case we need to use it a-la-HTTP. Will it only send a message with offset values if there is a change in at least one of them, or what do you think about that? Could save a lot of network traffic for values that rarely change... eg. if you wanted to monitor taxi lights for example... Will you be able to subscribe to multiple offsets.read requests with different intervals or only one? Just curious as I'm not sure if that would be needed... I guess the same reasoning goes for whether or not one can stop receiving messages for something you have previously subscribed to...
Paul Henty Posted September 20, 2020 Report Posted September 20, 2020 Quote Will it only send a message with offset values if there is a change in at least one of them, or what do you think about that? That's a good idea. I'll put that in. Quote Will you be able to subscribe to multiple offsets.read requests ... Yes, you can set up multiple read requests each with their own interval. I think this is useful as not all information would need to be read at the same rate. It also makes sense to split the offsets up into logical groups, e.g. lights, engines etc. especially if the request only sends data if one of the offsets has changed. I'll be adding an 'offset.stop' so you can stop the request if you don't need it anymore. Paul 1
Firefly Posted September 20, 2020 Author Report Posted September 20, 2020 Excellent stuff. I assume you are thinking of sending all values when at least one changes... Wondering if it will make sense to even only send the values that have actually changed. Would save some bandwidth but would require client-side logic to check which ones are present.
Paul Henty Posted September 20, 2020 Report Posted September 20, 2020 Yeah I was thinking about that. Probably the best thing is to make it an option on the request. That way the user can decide if they want to check which values are present or not. It would also be a good way of knowing which values have changed. Some applications like flight recorders are mainly based on logging values changing. You would need to test for the change anyway so checking for the value to be present in the return message would be no less inconvenient. For people writing gauge type applications, they just wouldn't enable the option and get all value from the request back all the time (if at least one has changed). Paul 1
Andy Gilbert Posted September 25, 2020 Report Posted September 25, 2020 (edited) Hi, I'm just joining this thread as it is something I have been developing myself ( http/REST Bridge to FSUIPC using DLL) but rather than developing something that is already being worked on (and probably better!) I thought see if I can help or contribute in anyway (even if by testing). The reason behind this is a software I have developed which requires to send/receive to MSFS over http or web sockets (best option). Is there a working version I could test by any chance? Thanks Andy Edited September 25, 2020 by Andy Gilbert
Paul Henty Posted September 25, 2020 Report Posted September 25, 2020 Hi Andy, I have an initial version working well. It just does basic reading and writing of offsets at the moment. More will be added in the future to expose the all helper functions of the .NET Client DLL. I'm about half way through the documentation. I'm hoping to release it for beta testing early next week. I'll post again in this thread when it's ready. Your help with testing and any feedback will be very welcome. Paul
Andy Gilbert Posted September 25, 2020 Report Posted September 25, 2020 18 minutes ago, Paul Henty said: Hi Andy, I have an initial version working well. It just does basic reading and writing of offsets at the moment. More will be added in the future to expose the all helper functions of the .NET Client DLL. I'm about half way through the documentation. I'm hoping to release it for beta testing early next week. I'll post again in this thread when it's ready. Your help with testing and any feedback will be very welcome. Paul Sounds great, look forward to it. Happy to help. Andy
Paul Henty Posted September 29, 2020 Report Posted September 29, 2020 (edited) Hi Everyone, I have the first beta version of the WebSocket Server ready for testing. If you'd like to download it and test it out, please visit: http://fsuipcwebsockets.paulhenty.com/ On the website you can download the server program and read all the documentation. If you have the server running locally while you are browsing the site, there are working examples on some of the pages. For the server program you'll need the .NET Framework Version 4.6.2 or higher. If you are keeping your Windows up-to-date it should already be installed. Paul Edited September 29, 2020 by Paul Henty URL Corrected 1
John Dowson Posted September 29, 2020 Report Posted September 29, 2020 23 minutes ago, Paul Henty said: I have the first beta version of the WebSocket Server ready for testing. If you'd like to download it and test it out, please visit: http://fsuipcwebsocketserver/paulhenty.com/ Thanks Paul! I'll add this to the FSUIPC6 installer at some point as another optional 'extra'. It might also be worth adding functionality directly in FSUIPC to start/stop the http server (when installed), but that can come later. Btw, can you check the link address - I get a 'This site can’t be reached' message!
Paul Henty Posted September 29, 2020 Report Posted September 29, 2020 Quote I get a 'This site can’t be reached' message! Sorry, corrected now. Paul
Andy Gilbert Posted September 30, 2020 Report Posted September 30, 2020 Great stuff Paul, will have a play. It would be nice if this did get bundled with FSUIPC and can be controlled from FSCUIPC I am developing some software that communicates with my own bridge software and want to "offer" the ability for users to use FSUIPC if preferred (and for beneficial reasons) however, that means either adding the option to my end user software or to my bridge app, which will then connect to this which is turn talks to FSCIPC which then talks to MSFS! 😱 Obviously not an issue for you guys, this is something I am to try and resolve, just thinking of ways to cut down the amount of separate downloads required and to be run and managed at once. Andy
John Dowson Posted September 30, 2020 Report Posted September 30, 2020 1 hour ago, Andy Gilbert said: It would be nice if this did get bundled with FSUIPC and can be controlled from FSCUIPC I'll definitely consider this when I get around to writing the installer for FSUIPC7, but the control for this may come later, we'll see....
Andy Gilbert Posted September 30, 2020 Report Posted September 30, 2020 Thanks John, much appreciated. Andy
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now