Transport via MQTT

MQTT is a lightweight, publish-subscribe network protocol. Clients exchange messages via topics. A topic can be understood as a named channel or a thread in a discussion forum. The single elements of an aspect are mapped to topics as follows.

Topic Structure

When registering an MQTT aspect the following naming convention for topics is recommended:

<tenant-id>/<twin-id>/<namespace>/<version>/<aspect-name>

where

  • tenant-id is the ID of the tenant

  • twin-id is the ID of the twin where the aspect is assigned to

  • namespace is identical to the namespace part of the Aspect Model URN defined in SAMM

  • version is identical to the version part of the Aspect Model URN defined in SAMM

  • aspect-name is identical to the element-name part of Aspect Model URN defined in SAMM

Two aspect MQTT endpoint types are supported:

  • READ endpoint to retrieve aspect data.

  • OPERATIONS endpoint to execute an operation on the aspect. This requires an additional topic to allow communication in both directions. The following topic-naming convention is recommended:

    .../<aspect-name>/REQ
    .../<aspect-name>/RESP

Operation calls are then sent to the REQ topic and the result will be sent in the RESP topic.

MQTT-specific Payload

As detailed in section Payloads in SAMM all payload must be JSON encoded.
However, depending on the kind of the aspect element, additional information must be sent:

  • Property payload directly encodes the Property’s value according to its specified datatype

  • Events are always encoded as JSON object with the required fields timestamp and parameters.

  • Operations must be able to link requests published to the REQ-topic to their response which is published to RESP. For this, requests and responses are JSON objects that must contain the mandatory field id with a unique string as value. The response for a given request must then have the same value for id. The actual content of an Operation call is transmitted via the optional field params, carrying the Operation parameters as object, for the request, and the optional field result, containing the answer to the Operation call.

See the following table for details.

Table 1. Consume an event over MQTT

Aspect element

JSON Example Payload

...
:currPosition a bamm:Event;
    bamm:name "currPosition" ;
    bamm:parameters ( :timestamp :parameters ) ;
    bamm:preferredName "Current position"@en .
:longitude a bamm:Property ;
    bamm:name "longitude" ;
    bamm:characteristic :CharacteristicGeoCoordinate .
:latitude a bamm:Property ;
    bamm:name "latitude" ;
    bamm:characteristic :CharacteristicGeoCoordinate .
:CharacteristicGeoCoordinate a bamm:Characteristic ;
    bamm:name "CharacteristicGeoCoordinate" ;
    bamm:dataType xsd:float .
:timestamp a bamm:Property ;
    bamm:name "timestamp" ;
    bamm:characteristic bamm-c:Timestamp .
:parameters a bamm:Property ;
    bamm:name "parameters" ;
    bamm:characteristic :CharacteristicPosition .
:CharacteristicPosition a bamm-c:List ;
    bamm:name "CharacteristicPosition" ;
    bamm:dataType :Position .
:Position a bamm:Entity ;
    bamm:name "Position" ;
    bamm:properties ( :latitude :longitude ) .
{
  "timestamp": "2020-11-09T08:42:04.363188Z",
  "parameters": [
    {
      "latitude": 48.777110,
      "longitude": 9.180770
    }
  ]
}
Table 2. Trigger operation using JSON-RPC 2.0 over MQTT

Aspect element

JSON Example Payload for REQ

JSON Example Payload for RESP

:stopOperation a bamm:Operation ;
    bamm:output :stopped .
:stopped a bamm:Property ;
    bamm:name "stopped" ;
    bamm:characteristic bamm-c:Boolean .
{
  "jsonrpc": "2.0",
  "method": "stopOperation",
  "id": "6b66328a-6ea2-4268-9d3c-4cf1e80355e3"
}
{
  "jsonrpc": "2.0",
  "result": {
    "stopped": true
  },
  "id": "6b66328a-6ea2-4268-9d3c-4cf1e80355e3"
}
To allow late joining participants to update to the current state quickly, it is recommended to publish Properties as retained messages. The MQTT broker will then automatically resend the last published message to the client.