"Device" mode

In Device mode, a single MQTT connection is associated with one specific device.

In Device mode, devices exchange JSON-formatted messages with the Live Objects platform, providing the following capabilities:

  • Device connectivity status reporting

  • Device configuration reporting and updates

  • Resource version reporting and update requests

  • Command reception and response publication

  • Data message publication, storage, and processing in Live Objects

Interactive
Figure 1. Device and data management features

MQTT Connection setup

To establish an MQTT connection in Device mode, use the following credentials:

  • clientId: your device unique identifier (cf. Device Identifier (URN)). It must be between 1 and 128 characters long, containing no spaces or special characters except :, - or _

  • username: json+device (case sensitive)

  • password: a valid API key value with DEVICE_ACCESS role

To find more information regarding Live Objects MQTT endpoints, please refer to: MQTT endpoints

We strongly recommend using a secure connection (MQTTS port 8883).

As soon as the MQTT connection has been accepted by Live Objects, your device will appear as "ONLINE" in Live Objects, with various information regarding the MQTT connection.

Once you close the connection (or if the connection timeouts), your device will appear as "OFFLINE" in Live Objects.

MQTT Client identity (URN)

The "clientId" value, is used as MQTT client Id must be a valid Live Objects URN and conform to the following format:

urn:lo:nsid:{namespace}:{id}

Where:

  • namespace: your device interface identifier "namespace", used to avoid conflicts between various families of identifier (ex: device model, identifier class "imei", msisdn", "mac", etc.).

  • id: your MQTT custom ID (ex: IMEI, serial number, MAC address, etc.)

"namespace" and "id" must only contain alphanumeric characters (a-z, A-Z, 0-9) or : - _ and must avoid # / !.* | +

Examples:

urn:lo:nsid:tempSensor:17872800001W
urn:lo:nsid:gtw_M50:7891001
urn:lo:nsid:gtw-M200:7891:001

Device MQTT topics

Authorized MQTT actions for a device:

Direction Topic Description

Data message publication

publish to

dev/data

to publish a Live Objects JSON data message - JSON compliant with Live Objects specific schema

publish to

dev/v1/data/rawjson/{model}

to publish any JSON message - any JSON with its schema name as {model}

publish to

dev/v1/data/binary

to publish a binary data message and use a decoder associated to the device’s interface

publish to

dev/v1/data/binary/{encoding}

to publish a binary data message and use a decoder directly with the topic’s name

Command management

subscribe to

dev/cmd

to receive commands and announce remote command compatibility

publish to

dev/cmd/res

to return command responses

Configuration management

publish to

dev/cfg

to notify the current configuration or respond to a config update request

subscribe to

dev/cfg/upd

to receive configuration update requests and announce remote configuration update compatibility

Resource management

publish to

dev/rsc

to notify the current resource versions

subscribe to

dev/rsc/upd

to receive resource update requests and announce remote resource update compatibility

publish to

dev/rsc/upd/res

to respond to resource update requests

publish to

dev/rsc/upd/err

to notify resource update error

An AuditLog message will be sent if the device uses an unauthorized topic.

MQTT device provisioning

By default, any device with a valid API Key will be able to connect to Live Objects using MQTT protocol.

You can explicitly define the MQTT capability for a device (see 'Device management - Interfaces' in Swagger documentation).

A device with an interface provisioned as "connector:"mqtt" and "enabled":false will not be able to connect to Live Objects through MQTT protocol.

Data message publication

JSON data publication with Live Objects specific format

To publish JSON data into Live Objects with Live Objects DataMessage schema, your device must publish on the MQTT topic dev/data the following messages:

{
    "streamId": "<<StreamId>>",
    "timestamp": "<<timestamp>>",
    "model": "<<model>>",
    "value": {
       "<<key>>":"<<value>>"      // a free JSON object
    },
    "location": {
       "lat":<<>>,
       "lon":<<>>,
       "alt":<<>>,
       "accuracy":<<>>,
       "provider":<<>>
    },
    "tags": [<<tag1>>,<<tag2>>,...]
}

By using the MQTT topic dev/data with the Live Objects JSON DataMessage schema, you can provide specific information such as the measurement timestamp of your data. Data published by devices through MQTT will be processed by the Data enrichment logic.

Message fields:

  • streamId : (optional) identifier of the timeseries this message belongs to,

  • timestamp : (optional) date/time associated with the message, is ISO 8601 format,

  • model : (optional) a string identifying the schema used for the "value" part of the message, to avoid conflict at data indexing,

  • value : (mandatory) a free JSON object describing the collected information,

  • tags : (optional) list of strings associated to the message used to carry extra-information,

  • lat, lon : (optional) latitude, longitude details of the geo location associated with the message (in degrees),

  • alt : (optional) height from sea level (in meters),

  • accuracy : (optional) the value depends on the combination of the tools provided the geo location tools (provider),

  • provider : (optional) GPS, cellular or custom

If not provided and not set via the device definition, the "streamId" will be urn:lo:nsid:mqtt:{clientId}.
If not provided, the "timestamp" will be the publication timestamp.

Please read this chapter to have the complete dataMessage description.

Example:

{
    "streamId": "mydeviceTemp1234",
    "timestamp": "2020-10-13T12:15:02Z",
    "model": "tempV2",
    "value": {
        "temp": 12.75,
        "humidity": 62.1,
        "doorOpen": true
    },
    "location": {
        "lat": 48.86667,
        "lon": 2.33333,
        "alt": 35.2,
        "accuracy": 12.3,
        "provider": "GPS"
    },
    "tags": [ "CityNYC", "Prototype" ]
}

JSON data publication with any JSON payload

To publish any JSON data into Live Objects, your device must publish on the MQTT topic dev/v1/data/rawjson/{model}.
A Live Objects DataMessage will be generated using the provided information.
The "streamId" will be urn:lo:nsid:mqtt:{clientId}, if not set in the device definition
The "timestamp" will be the publication timestamp.
The mandatory "model" will be the model specified with the publication topic, for example "version1".

Example:

publish dev/v1/data/rawjson/version1 with MQTT Payload

{
   "temp": 12.75,
   "humidity": 62.1,
   "doorOpen": true
}

will generate the Live Objects dataMessage :

{
    "streamId": "urn:lo:nsid:mqtt:\{clientId\}",
    "timestamp": "2020-10-13T12:15:02Z",
    "model": "version1",
    "value": {
        "temp": 12.75,
        "humidity": 62.1,
        "doorOpen": true
    }
}

if you want to change the JSON schema of the payload, use another model to avoid indexing conflicts

Example:

publish dev/v1/data/rawjson/version2 with MQTT Payload

{
   "temp": 20.0,
   "humidity": 68.8,
   "doorOpen": {
      "status" : true,
      "since" : "2019-10-12T12:15:02Z"
   }
}

will generate the Live Objects dataMessage :

{
    "streamId": "urn:lo:nsid:mqtt:\{clientId\}",
    "timestamp": "2020-10-13T12:15:02Z",
    "model": "version2",
    "value": {
               "temp": 20.0,
               "humidity": 68.8,
               "doorOpen": {
                  "status" : true,
                  "since" : "2019-10-12T12:15:02Z"
                           }
               }
}

Binary/hexa data publication

There are two different ways to publish binary data in Live Objects:

Topic Description

dev/v1/data/binary

Useful if you pre-provisioned your device using http API or the web portal. You can specify the "encoding" when the interface is created in the device inventory and use the decoding service. (1)

dev/v1/data/binary/{encoding}

This topic allows to specify directly the "encoding" that is used to match with a decoder name provisioned in Live Objects. With this topic, you don’t have to declare the "encoding" in the device inventory.

In both ways, the "encoding" value must match with the "name" of the decoder you want to use to decode the payload.

(1) The workflow if you prefer to declare the encoding in the device inventory is:

  • Create or update the device’s interface in the device inventory using http API or the web portal. See more information here.

  • Publish to the topic dev/v1/data/binary

In both cases, when pushing binary data, a dataMessage will be generated with the following values:

  • streamId: device urn

  • timestamp: timestamp of MQTT publication

  • value.payload: binary content of MQTT publication as a string in hexBinary http://www.datypic.com/sc/xsd/t-xsd_hexBinary.html

  • model: if a model is set in the decoder then it will be added. if not, this field is empty

When you publish binary data into Live Objects, only binary or javascript encoders (public or private) can be invoked. The csv decoder would not work in this case.

Please refer to the decoding service section for decoders management.

Examples:

Using the topic dev/v1/data/binary/{encoding}

  • Considering the following binary decoder already provisioned in Live Objects:

{
    "encoding": "my_encoding_v0",
    "format": "float sent_value;",
    "enabled": true,
    "model":"my_encoding_model_v0"
}
  • Sending a MQTT message with following bytes 0x41200000 as a payload on topic dev/v1/data/binary/my_encoding_v0, it will generate and store the following message:

{
    "timestamp" : "2020-10-31T16:15:21.288Z,"
    "streamId" : "urn:lo:nsid:mqtt:123456,"
    "value": {
        "payload": "41200000",
        "sent_value": 10.0
    },
    "model": "my_encoding_model_v0"
}

Using the topic dev/v1/data/binary

  • Declaration of the encoding in the device’s interface using http API: PATCH /api/v1/deviceMgt/devices/{deviceId}/interfaces/{interfaceId}

{
  "connector": "mqtt",
  "nodeId": "123456",
  "enabled": true,
  "status": "ONLINE",
  "definition": {
    "encoding": "my_encoding_v0",        // the name of the decoder that will be used to decode the payload
    "clientId": "123456"
  }
}

Considering the same decoder than in the previous example.

  • Sending a MQTT message with following bytes 0x41200000 as a payload on topic dev/v1/data/binary, it will generate and store the following message:

{
    "timestamp" : "2020-10-31T16:15:21.288Z,"
    "streamId" : "urn:lo:nsid:mqtt:123456,"
    "value": {
        "payload": "41200000",
        "sent_value": 10.0
    },
    "model": "my_encoding_model_v0"
}

Configuration

Current Configuration

To notify Live Objects of its current configuration, your device must publish a message to the MQTT topic dev/cfg with the following JSON structure:

{
   "cfg": {
      "<<param1Key>>": {
         "t": "<<param1Type>>",
         "v": <<param1Value>>
      },
      ...
   }
}

Message fields:

  • param{X}Key: the identifier for the device configuration parameters,

  • param{X}Type : indicates the config parameter type between

    • "i32": the value must be an integer from -2,147,483,648 to 2,147,483,647,

    • "u32": the value must a positive integer from 0 to 4,294,967,295,

    • "str": the value is a UTF-8 string,

    • "bin": the value is a base64 encoded binary content,

    • "f64": the value is float (64 bits) value,

  • param{X}Value : the config parameter value.

Example:

{
   "cfg": {
      "log_level": {
         "t": "str",
         "v": "DEBUG"
      },
      "secret_key": {
         "t": "bin",
         "v": "Nzg3ODY4Ng=="
      },
      "conn_freq": {
         "t": "i32",
         "v": 80000
      }
   }
}

Update Configuration

When your device is ready to receive configuration updates, it can subscribe to the MQTT topic dev/cfg/upd from where it will receive messages of the following format:

{
   "cfg": {
      "<<param1Key>>": {
         "t": "<<param1Type>>",
         "v": <<param1Value>>
      },
      ...
   },
   "cid": <<correlationId>>
}

Message fields:

  • param{X}Key : The identifier of a device configuration parameter that must be updated,

  • param{X}Type, param{X}Value : the new type and value to apply to the parameter,

  • correlationId : an identifier that your device must set when publishing your new configuration, so that Live Objects updates the status of your configuration parameters.

Example:

{
   "cfg": {
      "logLevel": {
         "t": "bin",
         "v": "DEBUG"
      },
      "connPeriod": {
         "t": "i32",
         "v": 80000
      }
   },
   "cid": 907237823
}

Response publication

Once your device has processed a configuration update request, it must return a response to Live Objects by publishing on topic dev/cfg the current value for the parameters that were updated:

{
   "cfg": {
      "<<param1Key>>": {
         "t": "<<param1Type>>",
         "v": <<param1Value>>,
      },
      ...
   },
   "cid": <<correlationId>>
}

Message fields:

  • config : the new configuration of your device (complete or at least all parameters that were in the configuration update request),

  • correlationId : the correlationId of the configuration update request.

Example:

{
   "cfg": {
      "logLevel": {
         "t": "bin",
         "v": "DEBUG"
      },
      "connPeriod": {
         "t": "i32",
         "v": 80000
      }
   },
   "cid": 907237823
}

If the new value for a parameter is the one that was requested in the configuration update request, the parameter will be considered as successfully updated by Live Objects.

If the new value for a parameter is not the one request, the parameter update will be considered as "failed" by Live Objects.

Commands

Retrieve the command request

When your device is ready to receive commands, it can subscribe to the MQTT topic dev/cmd from where it can receive the following messages:

{
   "req":  "<<request>>",
   "arg": {
      "<<arg1>>": <<arg1Value>>,
      "<<arg2>>": <<arg2Value>>,
      ...
   },
   "cid":  <<correlationId>>
}

Message fields:

  • request : string identifying the method called on the device,

  • arg{X}, arg{X}Value : name and value (any valid JSON value) of an argument passed to the request call,

  • correlationId : an identifier that must be returned in the command response to help Live Objects match the response and request.

Example:

{
   "req":  "buzz",
   "arg": {
      "durationSec": 100,
      "freqHz":     800.0
   },
   "cid": 12238987
}

Response publication

To respond to a command, your device must publish the response to the MQTT topic dev/cmd/res with a message of the following format:

{
   "res": {
      "<<res1>>": "<<res1Value>>",
      "<<res2>>": "<<res2Value>>",
      ...
   },
   "cid":  <<correlationId>>
}

Message fields:

  • res{X}, res{X}Value : optional information returned by the command execution,

  • correlationId : a copy of the command correlationId value.

Example #1:

{
   "res": {
      "done": true
   },
   "cid": 12238987
}

Example #2:

{
   "res": {
      "error": "unknown method 'buzz'"
   },
   "cid": 12238987
}

Any response of the device will set the command state to PROCESSED and the optional information will be available in the command result.

Resources management

Current Resources publication

Once connected, your device can announce the currently deployed versions of its resources by publishing a message on MQTT topic dev/rsc with the following format:

{
   "rsc": {
      "<<resource1Id>>": {
         "v": "<<resource1Version>>",
         "m": <<resource1Metadata>>
      },
      "<<resource2Id>>": {
         "v": "<<resource2Version>>",
         "m": <<resource2Metadata>>
      },
      ...
   }
}

Message fields:

  • resource{X}Id : resource identifier,

  • resource{X}Version : currently deployed version of this resource,

  • resource{X}Metadata : (JSON object) (optional) metadata associated with this resource, useful to resource update.

Example:

{
   "rsc": {
      "X11_firmware": {
         "v": "1.2",
         "m": {
            "size": <<firmware size in mbytes>>,
            "md5": "<<firmware sign>>",
         }
      },
      "X11_modem_driver": {
         "v": "4.0.M2"
      }
   }
}

Resources update

When your device is ready to receive resource update request, it just needs to subscribe to MQTT topic dev/rsc/upd. Then, the device will receive the request as a message in the following JSON format:

{
   "id": "<<resourceId>>",
   "old": "<<resourceCurrentVersion>>",
   "new": "<<resourceNewVersion>>",
   "m": {
      "size": <<firmware size in mbytes>>,
      "md5": "<<firmware sign>>",
   },
   "cid": "<<correlationId>>"
}

Message fields:

  • resourceId : identifier of resource to update,

  • resourceCurrentVersion : current resource version,

  • resourceNewVersion : new resource version, for new firmware downloading,

  • correlationId : an identifier that must be returned in the resource update response to help Live Objects match the response and request.

Example:

{
   "id": "X11_firmware",
   "old": "1.1",
   "new": "1.2",
   "m": {
      "uri": "http://.../firmware/1.2.bin",
      "md5": "098f6bcd4621d373cade4e832627b4f6"
   },
   "cid": 3378454
}

Response publication

Once your device receives a "Resource update request", it needs to respond to indicate if it accepts or not the new resource version, by publishing a message on topic dev/rsc/upd/res with the following JSON format:

{
   "res": "<<responseStatus>>",
   "cid": "<<correlationId>>"
}

Message fields:

  • responseStatus : indicates the response status to the resource update request:

    • "OK" : the update is accepted and will start,

    • "UNKNOWN_RESOURCE" : the update is refused, because the resource (identifier) is unsupported by the device,

    • "WRONG_SOURCE_VERSION" : the device is no longer in the "current" (old) resource version specified in the resource update request,

    • "WRONG_TARGET_VERSION" : the device doesn’t support the "target" (new) resource version specified in the resource update request,

    • "INVALID_RESOURCE" : the requested new resource version has incorrect version format or metadata,

    • "NOT_AUTHORIZED" : the device refuses to update the targeted resource (ex: bad timing, "read-only" resource, etc.),

    • "INTERNAL_ERROR" : an error occurred on the device, preventing for the requested resource update,

  • correlationId : copy of the correlationId field from the resource update request.

Example #1:

{
   "res": "OK",
   "cid": 3378454
}

Example #2:

{
   "res": "UNKNOWN_RESOURCE",
   "cid": 778794
}

Response error

Device can report a custom resource update error by publishing a message on MQTT topic dev/rsc/upd/err with the following format:

{
   "errorCode":"ERROR_CODE",
   "errorDetails":"error details"
}

Message fields:

  • errorCode : (optional) device error code,

  • errorDetails : device error details

These fields are limited to 256 characters. Characters outside of this limit will be ignored.

Example:

{
   "errorCode":"DEV123.Z_FIRMW_CRC",
   "errorDetails":"error while loading firmware, bad CRC"
}