Skip to content

MindConnect MQTT Commanding

Overview

Commanding feature provides functionality for applications to send JSON data to MindConnect MQTT agents. The data could be a command and/or data associated with the command sent to the agents. This feature provides RESTful APIs for the applications to directly send the command and associated data to the agents. Once the MQTT agent is onboarded, the agent needs to subscribe to the agent's own Topic to receive commands. The agent can update the status of the command execution by sending a message on the agents' Topic.

The latest response from the agent is saved and can be retrieved using the REST APIs.

Prerequisites

Limitations

  • One Delivery Job can deliver the command to a maximum of 20 MQTT Agents.
  • The maximum payload size for the data to be sent to and from MQTT Agent is 4kB.

Getting Started

The APIs for Commanding are specified on APIs and Services. For accessing the Commanding APIs, App Credentials need to be generated and it should have either mdsp:core:msg.fullaccess or mdsp:core:msg.readonly role assigned, Refer Assign the Application Roles for roles assigned to the app.

The role mdsp:core:msg.readonly provides read-only scopes to the app credentials and mdsp:core:msg.fullaccess provides create and delete delivery jobs scopes to the app credentials.

The Client Id is defined in the below format for the agents:

Region Client Id Format
Europe 1 <clientId> = <tenant>_<AgentCertificate.Subject.CommonName>
Europe 2 <clientId> = <AgentCertificate.Subject.CommonName>

Here, <tenant> is the tenant name and <AgentCertificate.Subject.CommonName> is the Common Name attribute of the agent certificate subject. A single client id represents a single agent, and therefore, multiple connections using a single client id are not allowed. If you try to create multiple connections, the agent will keep reconnecting and MQTT messages will not be received.

Using Commanding APIs

The Commanding feature provides functionality for sending MQTT command to a list of agents for execution by creating a Delivery Job. As soon as a delivery job is created, the job data is sent to the listed agents to their respective agent topics.

The following validations are performed when a delivery job is created:

  • The provided list of clientIds should be present in MindSphere.
  • The maximum number of agents can be 20 in a delivery job.
  • Data size is restricted to 4KB.

Creating a delivery job

A Delivery Job can be created by sending the below JSON payload to the rest API endpoint. It accepts a JSON payload containing the name of the job, list of client ids, and the data associated with the command. The data needs to be a valid JSON object, it is intended only for the receiving agent.

POST /deliveryJobs

Sample Request:

{
  "name": "firmware update job",
  "clientIds": [
    "tenantId_device8"
  ],
  "data": {
    "additionalProp1": "string",
    "additionalProp2": "string",
    "additionalProp3": "string"
  }
}

Sample Response:

{
  "id": "21349765fe45652c8e126814c283a114",
  "name": "firmware update job",
  "clientIds": [
    "tenantId_device8"
  ],
  "tenantId": "mytenant",
  "status": "EXECUTING",
  "data": {
    "additionalProp1": "string",
    "additionalProp2": "string",
    "additionalProp3": "string"
  },
  "createdAt": "2011-08-12T20:17:46.384Z",
  "createdBy": "string"
}

Here, the ID generated (id) is used further to get, delete a delivery job, and get all commands associated with a given delivery job. From above example, the delivery job id is 21349765fe45652c8e126814c283a114.

Listing all delivery jobs

All delivery jobs can be fetched using the following endpoint. The response contains the page JSON node to indicate the total delivery jobs, current page, and total pages. The following endpoint is to list all delivery jobs:

GET /deliveryJobs

Sample Response:

{
  "_embedded": {
    "deliveryJobs": [
      {
        "id": "21349765fe45652c8e126814c283a114",
        "name": "Firmware update job",
        "status": "EXECUTING",
        "createdAt": "2022-01-19T03:34:02.030+00:00"
      },
      {
        "id": "2c9180877e2f647a017e7066082d005e",
        "name": "Actuator Control job",
        "status": "EXECUTED",
        "createdAt": "2022-01-19T03:34:02.030+00:00"
      }
    ]
  },
  "page": {
    "size": 0,
    "totalElements": 0,
    "totalPages": 0,
    "number": 0
  },
  "_links": {
    "self": {
      "href": "string"
    },
    "first": {
      "href": "string"
    },
    "prev": {
      "href": "string"
    },
    "next": {
      "href": "string"
    },
    "last": {
      "href": "string"
    }
  }
}

Info

The maximum page size for this API is 100.

Filtering Delivery Jobs

Alike other MindSphere APIs, the Filtering of delivery jobs is supported. JSON string describing filter operations is performed on delivery jobs to be returned.

The following fields and operations are supported:

  • name : eq, in, endsWith, startsWith, contains

  • createdAt : before, after, between

Examples:

Unencoded example filter value to fetch all delivery jobs for name "test":

{ "name": "test" }

{ "name": { "startsWith" : "test" }}

Unencoded example filter value to fetch all delivery jobs based on createdAt:

{"createdAt": {"between": "[2021-11-06T13:46:00Z, 2021-11-11T13:46:00Z]"}}

{"createdAt": {"after": "2021-11-06T13:46:00Z"}}

{"createdAt": {"before": "2021-11-06T13:46:00Z"}}

Managing delivery jobs

A specific delivery job can be fetched using the delivery job id. The job contains the consolidated execution status based on all the individual command statuses. A command can be fetched using delivery job id and command id. Here, the id is the job id generated while creating a delivery job. Each command under a delivery job also has an id known as commandId, and it can be used to fetch specific command execution and response.

  • Use the following endpoint to get a delivery job:
GET​ /deliveryJobs​/{id}
Sample Response:

```json
{
    "id": "21349765fe45652c8e126814c283a114",
    "name": "Firmware update job",
    "clientIds": [
        "tenantId_device8"
    ],
    "tenantId": "tenantId",
    "status": "EXECUTED",
    "data": {
        "additionalProp1": "string",
        "additionalProp2": "string",
        "additionalProp3": "string"
    },
    "createdAt": "2022-01-19T03:34:02.030+00:00",
    "createdBy": ""
}
```
  • Use the following endpoint to delete a delivery job:
DELETE /deliveryJobs​/{id}
  • Use the following endpoint to get all the commands for a given delivery job. Successful invocation returns the status of all commands as a JSON array.
GET /deliveryJobs​/{id}​/commands
Sample Response:

```json
{
    "_embedded": {
        "commands": [
            {
                "id": "2c9180877e2f647a017e70660833005f",
                "clientId": "tenantId_device8",
                "tenantId": "tenantId",
                "status": "EXECUTED",
                "updatedAt": "2022-01-19T03:34:05.000+00:00"
            }
        ]
    },
    "_links": {
        "self": {
            "href": "https://gateway.eu1.mindsphere.io/api/commanding/v3/api/v3/deliveryJobs/21349765fe45652c8e126814c283a114/commands{?filter}",
            "templated": true
        }
    },
    "page": {
        "size": 20,
        "totalElements": 1,
        "totalPages": 1,
        "number": 0
    }
}
```
  • Use the following endpoint to get the command associated with a delivery job using command id. The response contains the response sent by the Agent along with the execution status sent by the agent.
GET /deliveryJobs/{id}/commands/{commandId}
Sample Response:

```json
{
    "id": "2c9180877e2f647a017e70660833005f",
    "clientId": "tenantId_device8",
    "tenantId": "tenantId",
    "status": "EXECUTED",
    "response": {
        "additionalProp1": "string",
        "additionalProp2": "string",
        "additionalProp3": "string"
    },
    "updatedAt": "2022-01-19T03:34:05.000+00:00"
}
```

Filtering Delivery Job Commands

Filtering of commands can be done using the JSON filter. The JSON string describing filter operations performed on commands associated with a delivery job will be returned.

The following fields and operations are supported:

  • clientId : eq, in, endsWith, startsWith, contains

  • status : eq, in, endsWith, startsWith, contains

  • updatedAt : before, after, between

Examples:

Unencoded example filter value to fetch all commands associated with delivery job for clientId "tenantId_testDevice":

{ "clientId": "tenantId_testDevice" }

{ "clientId": { "startsWith" : "tenantId" }}

Unencoded example filter value to fetch all commands associated with the delivery job for status "EXECUTED":

{ "status": "EXECUTED" }

{ "status": { "startsWith" : "EXE" }}

Unencoded example filter value to fetch all commands associated with delivery job based on updatedAt:

{"updatedAt": {"between": "[2021-08-06T13:46:00Z, 2021-11-11T13:46:00Z]"}}

{"updatedAt": {"after": "2021-11-06T13:46:00Z"}}

{"updatedAt": {"before": "2021-11-06T13:46:00Z"}}

Info

The possible statuses of a Delivery Job are EXECUTING, EXECUTED, and no other values are allowed. It is set to EXECUTING by default when a Delivery Job is created. The status is set to EXECUTED when all corresponding commands are set to the final state either EXECUTED or FAILED. Any single command in EXECUTING state will show the delivery job status as EXECUTING. The Command status is responded by the Agent via a response message, the same is set to the corresponding command.

Info

The Commanding APIs are only accessible using App Credentials.

For more information, refer Commanding Feature Sync API specifications.

Using Async APIs

The Commanding feature provides the capability for the MQTT Agents for subscribing to the MQTT Messages sent via REST APIs. The MQTT Agent can respond with the status and the JSON response MQTT message to a topic. The latest response message is saved and can be seen via REST APIs.

Subscribing for Commands

This operation is used to receive the command to be executed by the agent.

Region Operation
Europe 1 tc/{tenantId}/{clientId}/i/cmd_v3/c
Europe 2 devices/{clientId}/messages/devicebound/# , topic with property bag is devices/{clientId}/messages/devicebound/cmd_v3=c

Payload example:

{
  "id": "99609765fed2452c8e126814c283a27f",
  "data": {
    "jobId": "21349765fe45652c8e126814c283a114",
    "createdAt": "string",
    "payload": {
      "property1": "string",
      "property2": "string"
    }
  }
}

Attention

The message will not be received if the MQTT Agent is disconnected from the broker. The Agent should always be connected to the MQTT Broker for continuous reception of the commands.

Publishing Command Execution Status

This operation is used to publish the command execution status and progress.

Region Operation
Europe 1 tc/{tenantId}/{clientId}/o/cmd_v3/u
Europe 2 devices/{clientId}/messages/events/cmd_v3=u

Payload example:

{
  "id": "11609765fed2452c8e126814c283a289",
  "requestId": "99609765fed2452c8e126814c283a27f",
  "data": {
    "timestamp": "2011-08-12T20:17:46.384Z",
    "jobId": "21349765fe45652c8e126814c283a114",
    "status": "EXECUTING",
    "response": {
      "property1": "string",
      "property2": "string"
    }
  }
}

Info

The possible statuses of a Command are EXECUTING, EXECUTED, FAILED, and no other value is allowed. The Command status responded via the response message is set to the corresponding command. The command statuses are consolidated to form the delivery job status. If multiple responses for the same command are sent, the latest response is saved for retrieval using REST APIs.

Command Response

  • The id from the response JSON needs to be unique.
  • The requestId needs to be the same as in the command request received from the subscribed message.
  • The jobId needs to be the same as received in the subscribed message.
  • The timestamp from the response message should be greater than the received subscribed message.

For more information, refer Commanding Feature Async API specifications.

Any questions left?

Ask the community


Except where otherwise noted, content on this site is licensed under the MindSphere Development License Agreement.


Last update: July 29, 2022