SmarterLink Protocol Specification

Status: Released (protocol version 1.0)

Library version: 1.0.1


1. Overview

SmarterLink is a publish/subscribe messaging protocol for distributed communication in industrial manufacturing environments. It defines how participants (devices and software systems with distinct roles) exchange events and data over MQTT.

SmarterLink deliberately avoids MQTT 5 features to ensure compatibility with a wide range of brokers.


2. Participants

2.1 Identity

Every SmarterLink participant has a Participant ID: a plain string that must be unique across the entire SmarterLink network (all sites). The Participant ID appears in MQTT topic paths and must not contain MQTT reserved characters (/, +, #, $).

2.2 Roles

Every participant is assigned a Role that describes its function in the system. Four canonical roles are defined:

Role Topic Segment Description
Data Producer producers Acquires and publishes production data (images, measurements, etc.)
Data Processor processors Consumes and processes data from producers, publishes results
Data Store store Persists data and serves files to other participants
Human-Machine Interface hmi Displays information and interacts with operators

Custom roles are permitted but carry no standard event definitions.


3. Transport

3.1 MQTT

SmarterLink is designed to work with MQTT 3.1.1. The protocol deliberately avoids MQTT 5 features to ensure broad broker compatibility.

3.2 Topic Hierarchy

SmarterLink topics follow the Universal Namespace (UNS) convention:

smarter-link/<site>/<area>/<sub-area>/<station>/<role>/<participant-id>/<event-name>
Level Name Description
1 smarter-link Fixed protocol root identifier
2 site Site or facility identifier
3 area Area within the site
4 sub-area Sub-area within the area
5 station Station
6 role Role segment (see §2.2), or _ if not applicable
7 participant-id Publishing participant's ID prefixed with ~ (e.g. ~cam-01), or _ if not applicable
8 event-name Event name in kebab-case

When a level is not applicable to a particular event it is set to _ rather than omitted. All topics therefore always have exactly 8 levels, which makes subscription filter construction predictable.

Example:

smarter-link/site-x/area-1/sub-1/station-a/producers/~cam-01/component-image-acquired

3.3 Segment Constraints

Topic segments must not contain /, +, #, or $. Participant IDs must be unique across the entire network, not just within a single station.

Two characters are reserved as segment-type indicators:

Character Reserved for Example
~ Participant ID segments ~cam-01
: File descriptor segments fs:00, fr:99

Other segments (site, area, sub-area, station, role, event name) should avoid these characters.


4. Message Format

All SmarterLink messages, except raw file transfer chunks, are JSON objects.

4.1 Envelope

Every message has two required top-level fields:

{
  "header": { ... },
  "payload": { ... }
}

4.2 Header

Field Type Required Description
payloadType string yes Simple type name of the payload (e.g. "ActiveJobUpdated"). Used by receivers to select the correct deserialization type.
monotonicCounter integer (int64) no A value that increases with each successive message from a given sender. May be a UTC timestamp (e.g. .NET ticks since Unix epoch) or a simple counter. Used to determine relative message order.
protocolRevision integer yes Integer revision number of the SmarterLink protocol. Each stable protocol release maps to a specific revision number (see §9.1). Current value: 0.
userData string no Optional application-defined string. Passed through the protocol without interpretation.

4.3 Payload

Every payload carries a version field for independent schema evolution. All remaining fields are event-specific.

Field Type Required Description
version integer yes Schema version of this payload type.

4.4 Serialization

  • All JSON property names are camelCase.
  • JobId, ComponentId, and ParticipantId serialize as plain strings.
  • Location serializes as a URI string.
  • HashingFunction serializes as a string identifier (e.g. SHA-256). Supported values are defined in the SmarterLink File Transfer Protocol.
  • Required fields must always be present. Absent optional fields are treated as null by receivers.

4.5 Example

{
  "header": {
    "payloadType": "ActiveJobUpdated",
    "monotonicCounter": 638765432100000000,
    "protocolRevision": 0,
    "userData": null
  },
  "payload": {
    "version": 1,
    "jobId": "job-2024-001"
  }
}

5. Core Data Types

5.1 Identifiers

Type Wire Format Constraints
ParticipantId string Must be unique network-wide; no /, +, #, $
JobId string Can be used to correlate SmarterLink payloads with external job management systems.
ComponentId string Can be used to correlate SmarterLink payloads with external Component/Part/CAD management systems.

5.2 Location

A Location is a URI string that references a resource accessible by SmarterLink Participants.

All URI schemes are permitted, however SmarterLink leaves it the the Participants to work out how to use the URIs.

SmarterLink provides an optional protocol for File Transfers overt MQTT.

File locations in the protocol use the smarterlink:// scheme (see §8.2).

5.3 JobConfig

A JobConfig is a free-form JSON object ({ "key": value, ... }) carrying job-specific parameters. Its schema is entirely application-defined. It is typically published out-of-band (e.g. via an application-defined custom payload or a side-channel) rather than as a standard SmarterLink event.


6. Standard Events

6.1 Job Events

Job events are scoped to a station, not to a specific participant. Both the role and participant-id levels are _.

Topic pattern: smarter-link/<site>/<area>/<sub-area>/<station>/_/_/<event-name>


activeJobUpdated

Signals that the active job for a station has changed.

Field Type Required
version integer yes
jobId JobId yes

jobFileAvailable

Signals that a file associated with a job (e.g. a recipe or configuration) is available for download.

Field Type Required
version integer yes
jobId JobId yes
fileId string yes
location Location yes

6.2 Data Producer Events

Published by Data Producer participants. The participant-id level identifies the specific producer.

Topic pattern: smarter-link/<site>/<area>/<sub-area>/<station>/producers/~<participant-id>/<event-name>


componentImageAcquired

Signals that an image of a component has been acquired and is available for download.

Field Type Required
version integer yes
componentId ComponentId yes
fileId string yes
location Location yes
jobId JobId yes

userInformationAcquired

Carries operator-entered or operator-associated information for a component.

Field Type Required
version integer yes
componentId ComponentId yes
fileId string yes
location Location yes
jobId JobId yes
information Mapping (string → string) yes

inspectionSystemStatusAcquired

Reports status information from a Data Producer participant.

Field Type Required
version integer yes
participantId ParticipantId yes
information Mapping (string → string) yes

6.3 Data Processor Events

Published by Data Processor participants.

Topic pattern: smarter-link/<site>/<area>/<sub-area>/<station>/processors/~<participant-id>/<event-name>


componentAnalysisUpdated

Signals that analysis results for a component are available.

Field Type Required
version integer yes
componentId ComponentId yes
fileId string yes
location Location yes
jobId JobId no

componentReportUpdated

Signals that a consolidated report for a component has been updated.

Field Type Required
version integer yes
componentId ComponentId yes
fileId string yes
location Location yes
jobId JobId no

7. Subscriptions

Participants subscribe using MQTT topic filters. Standard MQTT wildcard characters apply:

  • +: matches exactly one topic level
  • #: matches the remainder of the topic from that level onward (must be last)

Common subscription patterns:

Intent Filter
All job events at a station smarter-link/<site>/<area>/<sub-area>/<station>/_/_/+
Specific job event smarter-link/<site>/<area>/<sub-area>/<station>/_/_/<event-name>
Specific Data Producer event from any producer smarter-link/<site>/<area>/<sub-area>/<station>/producers/+/<event-name>
All events from a specific producer smarter-link/<site>/<area>/<sub-area>/<station>/producers/~<participant-id>/+
All events from all producers smarter-link/<site>/<area>/<sub-area>/<station>/producers/#
All events from all processors smarter-link/<site>/<area>/<sub-area>/<station>/processors/#
All events at a station smarter-link/<site>/<area>/<sub-area>/<station>/#
All SmarterLink events site-wide smarter-link/<site>/#

8. Custom Payloads

Custom payloads are a deliberate escape hatch for use cases that do not fit the standard typed event model (for example, integrating with a third-party system, sending application-specific configuration, or establishing application-defined side-channels). Publishers should follow standard SmarterLink conventions (topic structure, envelope format) as closely as possible; the flexibility exists for cases where strict conformance is not achievable.

8.1 Envelope

A custom payload message uses the standard SmarterLink JSON envelope (§4.1). The header is identical to any other message. The payloadType field carries an application-defined string (e.g. "JobConfig") rather than a standard event type name.

{
  "header": {
    "payloadType": "JobConfig",
    "monotonicCounter": 638765432100000000,
    "protocolRevision": 0,
    "userData": null
  },
  "payload": { }
}

The payload value is an arbitrary JSON object. Its schema is entirely application-defined.

8.2 Topic

Publishers should use the standard SmarterLink topic hierarchy (§3.2) wherever possible. Deviation is permitted when the standard structure cannot reasonably be applied, for example when the publisher has no meaningful role or participant identity in the SmarterLink sense.

8.3 Receiver Behaviour

Receivers identify custom payloads by the payloadType value in the header. If a receiver does not recognize the payloadType, it should ignore the message.


9. File Transfers

9.1 Using Data Store Intermediate (Preferred Approach)

The preferred way to share files between participants is through a Data Store participant. A sender uploads the file to the Data Store (via any suitable side-channel, e.g. HTTP) and then publishes a SmarterLink event carrying a Location URI that points to it. Receivers can fetch the file independently, at their own pace, without any coordination with the sender. This promotes decoupled, asynchronous interactions and avoids holding MQTT resources open for the duration of the transfer.

The MQTT file transfer protocol described in the remainder of this section should only be used when:

  • no Data Store participant is available in the deployment, or
  • the use case genuinely requires a synchronous, point-to-point transfer over MQTT.

9.2 File Transfer Over MQTT

SmarterLink includes a built-in file transfer mechanism for exchanging binary files (images, reports, recipes, etc.) directly over MQTT. It is loosely adapted from the AWS IoT Core file delivery approach.

All file transfer negotiation messages use the standard SmarterLink JSON envelope. Raw file chunks are the sole exception: they are published as binary with no envelope.

The full specification for this protocol is defined in SmarterLink File Transfer Protocol.


10. Versioning

10.1 Protocol Revision

The protocolRevision field in the message header is an integer that identifies the revision of the entire SmarterLink protocol, not just the envelope format. Integer revision numbers are used in messages to keep parsing simple and implementation-agnostic.

Stable protocol releases are identified by a human-readable version number (e.g. 1.2). Each stable release formally declares which protocolRevision integer it corresponds to, allowing implementations to map between the two. Pre-release revisions carry no such mapping guarantee.

Stable Release Version Protocol Revision
1.0 0

10.2 Payload Schema Versions

Each payload type carries its own version field for independent schema evolution.