Editor: MQTT External Integration
Description
This guide will walk through the specifics of using MQTT within Nominal Editor simulations. MQTT can be used to send and receive data from external sources, such as External Hardware, External Software, or even other Nominal Editor simulations running in parallel. The advantage of MQTT integration is that as an Internet of Things (IoT) protocol, it can support hundreds of active connections. Before starting this guide, it is recommended that users are familiar with the “Integrating External Hardware or Software” tutorial and the fundamental principles of MQTT, which can be found at https://mqtt.org/.
Warning
The functionality for MQTT depends on a valid Internet connection and, depending on the use, a valid port that can be opened. As such, the functionality of this feature may depend on the environment in which Nominal Editor is being run. Cloud deployments, for example, may not run MQTT as expected.
Connection and Configuration
The first step for any external integration is to configure and establish a connection. Nominal Editor supports being an MQTT Client and Broker. It is also possible for one simulation instance of Nominal Editor to have multiple MQTT clients active whilst also acting as the MQTT Broker. To add an MQTT Client to an existing simulation, the Construct Object From Class
Blueprint function needs to be called, with the class set to MQTT Client. The same approach is required when creating an MQTT Broker, which is known as a Server.
Once the MQTT Broker has started, or if connecting to an external broker such as MQTT Websocket Client (hivemq.com), the MQTT Connect
function needs to be called. The Connection function requires the MQTT Broker and Port to connect to as well as the ClientID to use. To use MQTT in a localhost configuration, simply use localhost as the server. Due to MQTT’s Asynchronous nature, it is recommended that the Wait for Connection function is then called the pause the Unreal thread until the client or clients are connected to their configured MQTT Brokers. The Wait for Connection
function has a timeout specified in seconds.
Note
HiveMQ is a public broker. Users are advised to avoid sending any sensitive or confidential data over MQTT using this broker, or any other unmanaged brokers.
Bidirectional Data Flow
Once connections have been established, data can start flowing in and out of the simulation. Sending Data over MQTT is referred to as publishing, as the data is published to a specified MQTT topic. To assist in publishing simulation data, a Publish Message
function has been created that will publish the payload of a Nominal Systems message. The screenshot below shows the publishing of the Body States Message from a spacecraft over MQTT. Additional MQTT publishing functions exist for Byte Array
, Integer
, Float
and String
. Due to MQTT’s asynchronous nature, a Wait For Completion
function exits to pause the thread until the message has been published.
To receive data over MQTT, the first step is to be subscribed to the desired MQTT topic. If the MQTT topics are predefined, it is recommended that this occurs at the end of the Connection
and Configuration steps previously outlined. This minimizes the chance that the MQTT Client will miss any initial data flow.
To read the data on an MQTT topic, matching receive functions have been created for each of the MQTT publish functions. To receive the Nominal Systems Body States message from earlier the Read to Message
function is used. The received message payload can then be used to write any Body States message. Refer to the “Editor: Using Messages
” tutorial to learn more about Nominal’s messaging system.
As MQTT is asynchronous, users can call the Wait for Messages
function when receiving data over MQTT. This will pause the Unreal thread until the target number of messages has arrived or if the timeout has been exceeded.
To stop receiving data from an MQTT, the Unsubscribe
function is used and requires the topic to unsubscribe from.
Simulations can also be structured to use the MQTT blueprint pure functions to trigger certain data flow events, such as reading and decoding messages or publishing to other MQTT topics.
Disconnecting MQTT
Once a simulation is completed, or if an MQTT client needs to disconnect early, the MQTT Disconnect Client
function is used. It is recommended that the disconnect function is also called on Event End Play
within the level blueprint to ensure the client is disconnected. Whilst this won’t close the connection cleanly in the event of a software crash, it will create a clean disconnect the majority of the time and is still advised as a backup if the client is meant to disconnect on a specific instruction received over MQTT. To shut down an MQTT Broker, the Shutdown
function can be used with the MQTT client disconnect function call. However, before the shutdown function is used, it is also advised that the Disconnect Client
or Disconnect All Clients
function is called, to trigger the MQTT clients to disconnect.