Feature Proposal: REST/WebSocket API #916
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Hi,
I would like to propose a new "major" feature for MobiFlight, a REST/WebSocket API that can be used to trigger inputs and receive output values.
Motivation
I started to play around with a minimal Arduino setup and a single encoder. Instead of having multiple encoders, I want to use this single encoder to control multiple functions in the cockpit. For this I utilized the MobiFlight preconditions, variables and joystick inputs to switch between different encoder modes. So pressing a button on a Joystick sets a MobiFlight variable and multiple encoder input configs with preconditions control which FlightSim variable updates. So far, so good.
The main problem with this approach is that this is only one way. It is not possible to get any information out of MobiFlight in which mode the encoder currently operates. This is where the REST/WebSocket API comes into play.
In the bigger picture, I think this would enable a completely new kind of applications to interact with MobiFlight and profit from the existing features, like the super nice Huphop integration. Stream Deck Plugins that can visualize output variables, iPad/Web Apps to build dashboards and probably many more.
REST/WebSocket API
The idea is to have a new device category (REST/WebSocket API) that can be used as input and output device.
UI Overview
Input
REST/WebSocket API
can be selected as an Input module. The value entered into theDevice
text field is basically the device identifier used with the API. For example, an HTTP POST request to/input/[device identifier]
would trigger the input using the value from the body of the POST request.Internally, this is handled as an
AnalogInput
. This might not be the cleanest solution, let me know what you think about it. It just was the easiest way to reuse the existing architecture.Output
Similar to the inputs, I added a new display type for the outputs as well. In contrast to the inputs, each output must have a unique device/endpoint name. The current value of an output can be received by sending an HTTP GET Request to
/output/[device name]
.The downside of only using a REST API is that it would be necessary to poll for new output values. Because of that, I also decided to implement a WebSocket API, so that messages could be pushed to clients when an output value changes.
Settings
The settings UI is pretty straight forward. The interface where the REST and WebSocket Server is listening can be configured (either
127.0.0.1
orAll Interfaces
) as well as a TCP port.Supported API Operations
Trigger input
POST /input/[device name]
, value inside POST body. Response, see WebSocket response below.Get value of REST/WebSocket API output device
GET /output/[device name]
, see WebSocket response below.Get value of all REST/WebSocket API output devices
GET /output/
, see WebSocket response below.When an output value changed (WebSocket only)
Error message (response only)
Architecture Details
As REST/WebSocket server, I added EmbedIO as dependency (MIT License).
The
RestApiManager
class is the entry point that starts both servers and is part of theExecutionManager
class.RestApiServer
andWebSocketApiServer
include the server methods that are called, when a new message is received. Those classes are pretty small.The whole message processing is done in the
MessageProcessor
class.namespace MobiFlight.RestWebSocketApi.Messages
), depending on theMessageType
field of the request.Supported messages are defined in the
MessageTypeEnum
. Adding new messages should be straight-forward.What needs to be done (at least)
Feedback
Please let me know what you think about this proposal. I am open to discuss any changes, maybe you have some additional/other ideas/wishes for the API. Even if you see no future in this feature, that's fine as well. Just let me know.
Best regards,
Philipp