How to communicate between BlueOS extensions?

Hello!

I am working on an application where the user can control a couple of instruments and see sensor data in the Cockpit. Since it’s not yet possible to develop Cockpit widgets without rebuilding the Cockpit, I’m creating a BlueOS extension with a user interface and will imbed it in an IFrame widget.

The thought is to create one extension that manages the user interface, and an extension for each instrument for controlling hardware. The instrument extensions would communicate with the user interface. Much of the hardware requires additional processing, so simply changing a PWM pin on the Navigator board (over MAVLink) isn’t sufficient. The hope is that this approach would be more modular and scalable than putting everything in one extension.

What would you recommend for communicating between the extensions?

My first thought was to host a server on the frontend extension and have the instrument extensions send requests to the server. I tested this out by creating two Docker containers and having one act as a server, the other as a client, with both on the host network, but have been running into networking problems where the server refuses to accept connections. I don’t think this is a BlueOS issue, but it has left me wondering if there is a simpler way to achieve all this.

Thank you!

Hello

You can check below steps -

  • Use shared memory, message passing, or events within the same environment.
  • Utilize browser storage like local storage or IndexedDB for data sharing.
  • Employ WebSocket for real-time communication between extensions.
  • Use browser’s event system for dispatching and listening to custom events within extensions.

Hope it helps you !

Thank you
nathaniel

Hi @peterg, welcome to the forum! :slight_smile:

Awesome!

Out of interest, what kind of instrument displays are you wanting to create? If it’s just data values then you could already avoid needing to create your own interface elements by just sending the values as NAMED_VALUE_* MAVLink messages, which then get automatically detected by Cockpit and can be shown in the VeryGenericIndicator mini-widgets.

We’re currently considering some significant reworking of how Cockpit manages data input sources, with the idea that more widgets should be able to tap into data that gets flagged as a relevant type (e.g. if you have depth data that’s not going through the autopilot, but should still be shown in a depth widget). Feel free to share any thoughts you have on that front :slight_smile:

If you do need input to / manual control over them though then the IFrame approach is at least a reasonable workaround while Cockpit isn’t easily dynamically extensible.

Given Docker containers are made for isolation, cross-extension communications are likely best handled via network servers and API requests or websockets, aside from when they can be readily handled by shared access to part of the filesystem (e.g. if one extension stores map data locally, several others could safely have read access to that stored data).

I’ll raise an issue to write some more documentation about this - I expect cross-compatibility will become more common as more extensions get developed.

This seems a bit odd, unless the frontend extension is intended to be very generic, and accept input from various optional backend instrument driver extensions. If the instruments are typically in a package / if the drivers don’t require much storage then it may be fine to just have a single extension managing all of them.

This sounds like an issue with the extension settings (i.e. the container bindings configuration). We typically recommend explicitly bridging to the vehicle’s network for extensions that require access to other APIs.