Scenario: Receiving Commands and Sending Responses using MQTTS

Use this scenario to receive unstructured raw JSON commands from the cloud and send device responses over MQTTS.

This scenario supports unstructured raw JSON commands only. Use an MQTTS client as a connected device, invoke a command from the Internet of Things Platform, receive the command on the device request topic, and publish a response to the response topic.

Step 1: Create or Select a Digital Twin Instance

Use a digital twin instance without a digital twin model or digital twin adapter. The instance must be directly connected and have an authentication ID. Save the instance OCID and External Key.

  • Select an existing digital twin instance without a digital twin model or digital twin adapter. The instance must be directly connected. Alternatively, follow the Console instructions in Creating a Digital Twin Instance. Select or paste a secret or certificate authentication OCID.

  • To create a digital twin instance without a digital twin model or digital twin adapter, use the oci iot digital-twin-instance create command:

    oci iot digital-twin-instance create \
      --iot-domain-id <iot-domain-OCID> \
      --display-name <display-name> \
      --auth-id <secret-or-certificate-OCID>
  • Run the CreateDigitalTwinInstance operation to create a digital twin instance without a digital twin model or digital twin adapter, or get an existing instance with the same configuration. The instance must be directly connected and have an authentication ID.

Step 2: Establish the MQTT Session Using Broker Credentials

This example uses MQTTX with MQTT 5.

  1. Download and set up MQTTX. See Getting Started with MQTTX.
  2. Create a connection and enter a name that contains no confidential information.
  3. Enter the digital twin instance external key as the Username.
  4. Enter the device credential as the Password. For testing with a vault secret, use the plain-text secret contents.
  5. For Host, select mqtts:// and enter <domain-short-id>.device.iot.<region>.oci.oraclecloud.com.
  6. Enter port 8883, enable SSL/TLS, and select a CA-signed server certificate.
  7. Configure a persistent MQTT 5 session so the broker can resume the command subscription after a brief disconnect:
    • Client ID: Enter a stable Client ID and reuse it each time the client reconnects.
    • Clean Start: Turn off this option.
    • Session Expiry Interval: Set a nonzero interval long enough for the expected disconnect, for example, 7200 seconds.
    • Last-Will-Retain: This setting controls only whether the Last Will message is retained; it does not control subscription persistence.
  8. Set Last Will QoS to 1 for at-least-once delivery of a disconnect notification.
  9. Select Connect.

Step 3: Subscribe to the Command Request Topic

The requestEndpoint in the command becomes the MQTT topic on which the device receives the command. For this example, subscribe to /endpoints/1234 with QoS 1.

  1. In MQTTX, select + New Subscription.
  2. Enter /endpoints/1234 as the Topic.
  3. Select 1 At least once from the QoS menu.
  4. Select Confirm.

MQTTX new subscription dialog with the command request endpoint and QoS 1.

Step 4: Define the Command in a JSON File

Define the command details in a JSON file to use when you invoke the raw JSON command.

Save this request as command.json:

{
  "requestEndpoint": "/endpoints/1234",
  "requestDuration": "PT3M",
  "requestDataFormat": "JSON",
  "requestData": {
    "temp": 33
  },
  "requestDataContentType": "application/json",
  "responseEndpoint": "/endpoints/4321",
  "responseDuration": "PT3M"
}
  • requestEndpoint is the MQTT topic to which the device subscribes to receive the command. Use the same value when you subscribe to the command request topic.
  • requestDuration is the period during which the platform can deliver the command. Use the ISO 8601 duration format. For example, PT3M is 3 minutes.
  • requestDataFormat identifies the request data as JSON.
  • requestData is the JSON payload delivered to the device.
  • requestDataContentType is the media type of the request data.
  • responseEndpoint is the MQTT topic to which the device publishes its response. If you have a dedicated response endpoint, such as /endpoints/<external-id>/response, use it here. Use the same MQTT topic in this field and when the device publishes the response.
  • responseDuration is the maximum time the platform waits for the response.

For information about file locations and path types, see Using a JSON File for Complex Input.

Step 5: Invoke a Raw JSON Command on a Device

Invoke the same command by using the Console, CLI, or API.

    1. Open the IoT domain and select Digital twin instances.
    2. Open the instance, select Actions, and select Send raw command.
    3. Enter /endpoints/1234 as the request endpoint and PT3M as the request duration.
    4. Select JSON and enter {"temp": 33}.
    5. Specify /endpoints/4321 and PT3M as the response parameters.
    6. Select Send raw command.
  • Use the oci iot digital-twin-instance invoke-raw-json-command command:

    oci iot digital-twin-instance invoke-raw-json-command \
      --digital-twin-instance-id <digital-twin-instance-OCID> \
      --request-endpoint "/endpoints/1234" \
      --from-json file://command.json
  • Run the InvokeRawCommand operation for the digital twin instance and use the values from command.json.

Step 6: Receive the Command and Publish a Response in MQTTX

  1. On the /endpoints/1234 subscription, confirm that MQTTX receives the request data:
    {
      "temp": 33
    }
  2. Before the response duration expires, publish a response to /endpoints/4321 with QoS 1:
    {
      "status": "accepted",
      "temp": 33
    }

MQTTX connected to the IoT device host.

MQTTX displaying a command message.

Command Response Scenarios
ScenarioDevice StateExpected Command StateComments
Not connectedNot connected and not subscribedREFUSEDCommand delivery fails immediately.
Connected but not subscribedConnectedREFUSEDThe device is online but cannot receive the command.
Subscribed but not connectedSubscription is in a persistent sessionPENDING to EXPIREDThe command waits and expires after the timeout.
Reconnects before timeoutInitially offline with a persistent sessionPENDING to SENTThe device receives the command after reconnecting.
Connected and subscribedConnected and subscribedSENTThe device receives the command.
One-way commandConnected and subscribedCOMPLETEDNo response is expected.
Two-way command without a responseConnected and subscribedNOT_RESPONDEDThe device does not respond before the response timeout.
Two-way command with a responseConnected and subscribedCOMPLETEDThe device publishes a response before the timeout.

Step 7: Monitor the Command's Delivery Status in APEX

After you configure APEX access to IoT data, use APEX to query raw command data.

  1. Get the IoT domain details to find the <domain-short-id-from-device-host>. In APEX, log in to the IoT domain's Workspace using this value as both the workspace name and database user name:
    <domain-short-id-from-device-host>__WKSP
    Note

    Notice the two underscores in __WKSP.
  2. Go to SQL Workshop, select SQL Commands, and select the read-only <domain-short-id-from-device-host>__IOT schema.
  3. Enter the following command. Replace <domain-short-id-from-device-host> and <digital-twin-instance-OCID> with the values for your environment, and then select Run:
    select *
    from <domain-short-id-from-device-host>__IOT.RAW_COMMAND_DATA
    where digital_twin_instance_id = '<digital-twin-instance-OCID>';
  4. In Results, review RESPONSE_DATA, delivery status, request and response endpoints, and timeout values.

To view a larger screenshot, right-click and open the image in a new browser tab.APEX SQL Commands results for raw command data with the response data column highlighted.