This specification conforms to Coaty MQTT Communication Protocol Version 3
This document specifies the common Coaty MQTT Communication Protocol that must be implemented by all language-specific Coaty MQTT communication bindings to be interoperable.
The reference implementation of this protocol can be found in the binding.mqtt.js repository on GitHub.
With a Coaty MQTT binding, Coaty communication events are transmitted via the MQTT publish-subscribe messaging protocol. The format of MQTT topic names and payloads conforms to the MQTT Specification Version 3.1.1.
General requirements for MQTT bindings are as follows:
Online
on connection to the MQTT broker, and
Offline
on disconnection.Note that MQTT allows applications to send MQTT Control Packets of size up to 256 MB. For Publish messages, this includes the message topic of size up to 64K, the payload, as well as some bytes of header data.
To debug MQTT messages published by a Coaty agent, you can use any MQTT client and subscribe to the
coaty/#
topic. We recommend MQTT Explorer, a cross-platform client with a graphical user interface for structured topic inspection.
Coaty communication event patterns are mapped onto MQTT publication and subscription messages. Coaty defines its own topic structure that comprises the following MQTT topic levels:
coaty
.UUIDs (Universally Unique Identifiers) must conform to the UUID version 4 format as specified in RFC 4122. In the string representation of a UUID the hexadecimal values “a” through “f” are output as lower case characters.
Note: Raw events and external IoValue events do not conform to this topic structure. They are published and subscribed on an application-specific topic string, which can be any valid MQTT topic that must not start with
<ProtocolName>/
.
A topic name for publication is composed as follows:
// Publication of one-way event
<ProtocolName>/<ProtocolVersion>/<Namespace>/<Event>/<SourceObjectId>
// Publication of two-way event (both request and response)
<ProtocolName>/<ProtocolVersion>/<Namespace>/<Event>/<SourceObjectId>/<CorrelationId>
The ProtocolVersion topic level represents the communication protocol version of the publishing party, as a positive integer.
The Namespace topic level must specify a non-empty string. It must not
contain the characters NULL (U+0000)
, # (U+0023)
, + (U+002B)
, and /
(U+002F)
.
To denote event types in the Event topic level, 3-character shortcuts are used:
Event Type | Shortcut |
---|---|
Advertise | ADV |
Deadvertise | DAD |
Channel | CHN |
Associate | ASC |
IoValue | IOV |
Discover | DSC |
Resolve | RSV |
Query | QRY |
Retrieve | RTV |
Update | UPD |
Complete | CPL |
Call | CLL |
Return | RTN |
When publishing an Advertise event the Event topic level must include a
filter of the form: ADV:<filter>
. The filter must not be empty. It must not
contain the characters NULL (U+0000)
, # (U+0023)
, + (U+002B)
, and /
(U+002F)
. Framework implementations specify the core type (ADV:<coreType>
) or
the object type (ADV::<objectType>
) of the advertised object as filter in
order to allow subscribers to listen just to objects of a specific core or
object type.
When publishing an Update event the Event topic level must include a filter
of the form: UPD:<filter>
. The filter must not be empty. It must not contain
the characters NULL (U+0000)
, # (U+0023)
, + (U+002B)
, and / (U+002F)
.
Framework implementations specify the core type (UPD:<coreType>
) or the object
type (UPD::<objectType>
) of the updated object as filter in order to allow
subscribers to listen just to objects of a specific core or object type.
When publishing a Channel event the Event topic level must include a channel
identifier of the form: CHN:<channelId>
. The channel ID must not be empty. It
must not contain the characters NULL (U+0000)
, # (U+0023)
, + (U+002B)
, and
/ (U+002F)
.
When publishing a Call event the Event topic level must include an operation
name of the form: CLL:<operationname>
. The operation name must not be empty.
It must not contain the characters NULL (U+0000)
, # (U+0023)
, + (U+002B)
,
and / (U+002F)
.
When publishing an Associate event the Event topic level must include an IO
context name of the form: ASC:<contextName>
. The context name must not be
empty. It must not contain the characters NULL (U+0000)
, # (U+0023)
, +
(U+002B)
, and / (U+002F)
.
For any request-response event pattern the receiving party must respond with an outbound message topic containing the original CorrelationID of the incoming message topic. Note that the Event topic level of response events must never include a filter field.
Each MQTT binding must subscribe to topics according to the defined topic structure:
// Subscription for one-way events
<ProtocolName>/<ProtocolVersion>/<Namespace>/<Event>/+
<ProtocolName>/<ProtocolVersion>/+/<Event>/+
// Subscription for two-way request events
<ProtocolName>/<ProtocolVersion>/<Namespace>/<Event>/+/+
<ProtocolName>/<ProtocolVersion>/+/<Event>/+/+
// Subscription for two-way response events
<ProtocolName>/<ProtocolVersion>/<Namespace>/<Event>/+/<CorrelationID>
<ProtocolName>/<ProtocolVersion>/+/<Event>/+/<CorrelationID>
These subscriptions, especially response subscriptions, should be unsubscribed
as soon as they are no longer needed by the agent. Since Coaty uses Reactive
Programming Observables
to observe communication events, MQTT subscription
topics should be unsubscribed whenever the corresponding observable is
unsubscribed by the application.
Note that the Namespace topic level must either specify a non-empty string
or a single-level wildcard (+
), depending on whether the agent should restrict
communication to a given namespace or enable cross-namespacing communication.
When subscribing to a response event, the Event topic level must not include an event filter.
When subscribing to an Advertise event, the Event topic level must include
the Advertise filter: ADV:<filter>
or ADV::<filter>
.
When subscribing to a Channel event, the Event topic level must include the
channel ID: CHN:<channelId>
.
When subscribing to an Update event, the Event topic level must include
the Update filter: UPD:<filter>
or UPD::<filter>
.
When subscribing to a Call event, the Event topic level must include the
operation name: CLL:<operationname>
.
When subscribing to an Associate event, the Event topic level must include
the IO context name: ASC:<contextName>
.
When subscribing to a response event, the CorrelationID topic level must include the CorrelationID of the correlated request.
Message payloads for the Coaty events described above consist of attribute-value pairs in JavaScript Object Notation format (JSON, see RFC 4627).
Message payloads must be serialized with a JSON serializer that encodes/decodes event data as a UTF-8 string.
Note: Payloads of Raw events and IoValue events with raw data do not conform to this specification. They are published as byte arrays encoded in any application-specific format.
Copyright (c) 2020 Siemens AG. This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.