1. Introduction

2. Overview

2.1. What is Live Objects?

Live Objects is a Software as a Service belonging to IoT & Data Analytics services.

Live Objects is a software suite for IoT / M2M solution integrators offering a set of tools to facilitate the interconnection between devices (or connected « things ») and business applications:

  • Connectivity Interfaces (public and private) to collect data, send command or notification from/to IoT/M2M devices,

  • Device Management :inventory, supervision, configuration, resources, campaign management…​,

  • Data Management and collect: Data Storage with Advanced Search features, but also: Message enrichment process, Decoding service and custom pipelines for external enrichment,

  • Message Routing between devices and business applications,

  • Event processing: Alarming with an event detection service by analyzing the data flows sent by devices or occurring on the devices themselves. When these events take place, Live Objects has notification mechanisms to complete the process.

Live Objects overview

Interactive

The public interfaces are reachable from internet. The private interfaces provide interfaces with a specific network (LoRa®).

The SaaS allows multiple tenants on the same instance without possible interactions across tenant accounts (i.e. isolation, for example a device belonging to one tenant could not communicate with a device belonging to an other tenant).

A web portal provides a UI to administration functions like manage the messages and events, supervise your devices and control access to the tenant.

2.2. Architecture

Live Objects SaaS architecture is composed of two complementary layers:

  • Connectivity layer: manages the communications with the client devices and applications,

  • Service layer: various modules supporting the high level functions (device management, data processing and storage, etc.).

Live Objects architecture

Interactive

2.3. Connectivity layer

Live Objects exposes a set of standard and unified public interfaces allowing to connect any programmable devices, gateway or functional IoT backend.

The existing public interfaces are:

MQTT is an industry standard protocol which is designed for efficient exchange of data from and to devices in real-time. It is a binary protocol and MQTT libraries have a small footprint.

HTTPS could be rather used for scarcely connected devices. It does not provide an efficient way to communicate from the SaaS to the devices (requiring periodic polling for example).

For more info, see "Message encodings" section

The public interfaces share a common security scheme based on API keys that you can manage from Live Objects APIs and web portal.

Live Objects is fully integrated with a selection of devices and network. It handles communications from specific families of devices, and translate them as standardized messages available on Live Objects message bus.

The existing private interfaces:

  • LoRa® interface connected with LoRa® network server,

    • to provision LoRa® devices

    • to receive and send data from/to LoRa® devices

Also, it may be possible that your devices are not complient with Live Objects interfaces. It is still possible to use the API for "external connector" feature:

"External connector" mode : a good fit for connect your custom backend who manage your devices and when your devices don’t support Live objects connectivity. This mode has an MQTT API described in mode "External connector".

2.4. Service layer

Behind the connectivity layers for devices, Live Objects is a platform with several, ready to use services to enhanced you IoT potential.

On the one hand, the data collect part with various services: internal enrichment, decoding and custome pipelines for external enrichment services.

On the other hand, these data can be publish into a FIFO and consume using MQTT "application" mode.

  • FIFO : the solution to prevent from message loss in the case of consumer unavailability. Messages are stored in a queue on disk until consumed and acknowledged. When multiple consumers are subscribed to the same queue concurrently, messages are load-balanced between available consumers. More info: FIFO mode,

  • Application mode : a good fit for real-time exchanges between Live Objects backend and your business application. Data messages exchanged are queued in the FIFO queuing bus mechanism mode "Application".

2.4.1. Device management

Live Objects offers various functions dedicated to device operators:

  • supervise devices and manage connectivity,

  • manage devices configuration parameters,

  • send command to devices and monitor the status of these commands,

  • send resources (any binary file) to devices and monitor the status of this operation.

Live Objects attempts to send command, resources or update the parameters on the device as soon as the device is connected and available.

For more info about device and connectivity inventory, see "Device and connectivity inventory" chapter.
For more info about device connectors, see "Device connectors" section.
For more info about device management, see "Device Management" chapter.

2.4.2. Data management

2.4.2.1. Data transformation

Live Objects can transform the published messages by using data enrichment, message decoding and external datamessage transformation by using custom pipelines.

For more info, see "Data transformation" chapter.

2.4.2.3. Data analysis and display

Live Objects allows to store the collected data from any connectivity interfaces. These data could be then retrieved by using HTTPS REST interface.

A full-text search engine based on Elastic search is provided in order to analyze the data stored. This service is accessible through HTTPS REST interface.

For more info, see "Data analysis" chapter.

2.4.3. Messages and Events Processing

2.4.3.1. SEP, SP and AP

Simple event processing service is aimed at detecting notable single event from the flow of data messages.

Based on processing rules that you define, it generates fired events that your business application can consume to initiate downstream action(s) like alarming, execute a business process, etc.

For more info, see "Simple Event Processing" section.

In the other hand, Live Objects allows to process the Activity processing (AP) service which aims at detecting devices that have no activity.

For more info, see "•Activity processing" section.

The State processing (SP) service aims at detecting changes in "device state" computed from data messages.

For more info, see "•State processing" section.

2.4.3.2. Routing and Alarming

The FIFO mode communication is based on the usage of topics to publish a messages with ensuring no message loss. It can forward or route messages to recipients without loss using FIFO Publication and FIFO subscription. You can also use the HTTP push forwarding after the message is processed by event processing service or message routing service. Those services give a notifications or give an alarm to the recipients on purpose.

2.5. Access control

2.5.1. API keys

API keys are used to control the access to the SaaS for devices/application and users to authenticate. You must create an API key to use the API.

For more info, see "API key" and "Role" chapters.

2.5.2. Users management

When an account is created, a user with administration priviledges is also created on the account. This administrator can add other users to the account and set their priviledges. These priviledges are defined by a set of roles. The users can connect to the Live Objects web portal.

2.6. Edge computing

In an advanced usage, you have some ways to integrate the IOT edge plateform which can collect, manage and store the business data. But more use cases need treatments close to devices to provide :

  • Local treatment with low latency and independency

  • interoperability with industrial protocols

  • Secure approach with keeping locally the business and critical data

3. Getting started

This chapter is a step-by-step manual for beginners with Live Objects giving instructions covering the basic use cases of the service. Here is a small process to begining with Live objects and help you to easy building a use case and end-to-end test.

  • If you have device you can starting to use it.

  • If you do not have a device, browse the instructions in this guide to build a usage that uses only simulators to replace a device. You can use your own device simulator and use MQTT or COAP protocol to connect your virtual device to Live Objects.

Requirements : the data message sent by device (or simulator) must respect the Live Objects data model.

Connect your device and retrieve data with Live Objects (steps by device category and connectivity)

Interactive

3.1. Log in

To log in to Live Objects web portal, connect to liveobjects.orange-business.com using your web-browser:

landing

  • Fill the Sign in form with your credentials:

    • your login,

    • the password set during the activation phase,

  • then click on the Sign in button.

You are redirected to your “Dashboard” page:

landing

3.2. Connect and test your LoRa® device

LoRa® devices need to be registered on Live Objects to send messages.

To quick register your LoRa® device, use the Live Objects portal, liveobjects.orange-business.com.

3.2.1. Register your device

To register a LoRa® device, go to the Devices menu, select LoRa® in the list and click on Add device.

In the form, select the profile that corresponds to your device. If you do not know, select Generic_classA_RX2SF12. Enter your device’s DevEUI, AppEUI and AppKey. Depending on the LoRa® device you are using, these parameters are pre configured and they should come with the device, or you can configure the device resource with your own parameters. Then click on Register.

You can see your device in the Devices menu.

3.2.2. Connect your LoRa® device

When the device is registred then join LoRa® network and it would automatically connected to Live Objects. The device is now ready to send uplink data and begining to publish the data messages.

When you prefer using an API, see Register a LoRa® device

3.3. Simulating an MQTT device

To make a device or an application communicate with Live Objects using MQTT, you will need an API key.

3.3.1. Create an API key

To create an API key, go to the Configuration menu, click on Api keys in the left menu and create a new API key. Select at least the role "DEVICE_ACCESS".

landing

As a security measure, you can not retrieve the API key again after you have closed the API key creation results page. So, note it down to work with the MQTT client, during the scope of this getting started.

landing

3.3.2. Download your simulator tool

It is up to you to choose your favorite MQTT client or library. We will use here MQTTBox. This client is available on Win/MacOSX/Linux and is free (until now). Download and install the last version of MQTTBox.

3.3.3. Connect your simulator

We will start by creating a new Connection profile and configure it based on the device mode set up.

General panel:

You will configure here the endpoints of Live Objects including authentication information. In this panel, you can set :

landing

Credentials panel:

  • username: json+device : for device mode MQTT connection

  • password: the API key that you just created with the "DEVICE_ACCESS" role

landing

3.3.4. Verify status

We can simulate a device connection to Live Objects with MQTTbox client by clicking on Connect button of MQTTbox client.

landing

In Live Objects portal, go to the Devices page, the connected device has "green" status.

landing

3.3.5. Publishing data messages

We will use MQTTbox client with device mode to send data message as a device would do.

Data message must be published on this topic: dev/data.

Message:

{
    "streamId" : "urn:lo:nsid:sensor:2327398!measures",
    "location": {
        "lat": 48.86667,
        "lon": 2.33333
    },
    "model": "temperatureDevice_v0",
    "value": {
        "status" : "online",
        "tempreature rise frequency" : 10,
        "temp" : 17.25
    },
    "tags": [ "City.NYC", "Model.Prototype" ]
}

With:

  • streamId: the streamId of the message, the message will be forwarded to a topic containing the streamId so an application connected to Live Objects can retrieve messages

  • timestamp: the timestamp of the message, this field is optionnal, if not set by the device, Live Objects will set it with the time of arrival,

  • location: the location of the device, this field is optionnal,

  • model: the model of data contained in the v field, (more about data model)

  • value: the value, this is a free field to store device specific data such as the device sensor values,

  • tags: a list of tags, this field is optionnal.

landing

3.4. Device Management basics

3.4.1. Sending a command to a LoRa® device

Messages sent by LoRa® devices to Live Objects are called uplinks. Messages sent by Live Objects to LoRa® devices are called downlinks.

To send a command, go to Devices then select your LoRa® device in the list and go to Downlink tab. Click on Add command, enter a port number between 1 and 223 and enter data in hexadecimal, 0A30F5 for example. The downlink will be sent to your device after the next uplink.

3.4.2. Sending a command to an MQTT device

You must first subscribe to the topic waiting for command "dev/cmd". (Subscribe tab of MQTTbox)

Go to Devices then select your device in the list and go to Commands tab.

Click on add command then fill the event field with "reboot" then click on Register. The command will appear in MQTTbox client subscribe tab.

command request

 {
    "req":"reboot",
    "arg":{},
    "cid":94514847
  }

landing

A response can be sent to acknowledge the command received.

To send this response, you can publish a message to this topic "dev/cmd/res". (correlation identifier) must be set with the value received previously.

command response

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

Once published, the status of the command will change to "processed" in the portal commands history tab.

A correlation ID uniquely identifies each ‘request’, or the equivalent and used in your intercation with Live Objects API.

3.5. Accessing the stored data

There are several ways to access you device’s data:

  • Going back to Live Objects portal, you can consult the data message that was just stored. Go to Data then search for stream "urn:lo:nsid:dongle:00-14-22-01-23-45!temperature". The data message sent will appear.

landing

  • You can access data from the HTTPS interface.

  • You can perform complex search queries like aggregation using elasticsearch DSL HTTPS interface. See example in See example in Data API chapter

  • Through the MQTT interface, either your configured FIFO queue or your connected MQTT client will receive data messages.

3.6. Connect an application to collect your devices data

3.6.1. Using HTTPS to retrieve your devices' data

Data from you device can be retrieved using HTTPS API.

You will need an API key with the DATA_R role. You can create it as you did in the previous part.

The following endpoint enables you to retrieve data from a stream: https://liveobjects.orange-business.com/api/v0/data/streams/{streamId}

Example with a MQTT device:

GET /api/v0/data/streams/urn:lo:nsid:dongle:00-14-22-01-23-45!temperature
Host: https://liveobjects.orange-business.com
Header: X-API-KEY: <a valid API key with DATA_R role>

Example with a LoRa® device:

GET /api/v0/data/streams/urn:lo:nsid:lora:<DevEUI>
Host: https://liveobjects.orange-business.com
Header: X-API-KEY: <a valid API key with DATA_R role>

3.6.2. Using MQTTs to retrieve your device’s data

Data published by your devices can be consumed using the MQTT protocol.

You will need an API key with the BUS_R role. You can create it as you did in a previous part.

Then configure a FIFO queues to persist your device’s data until you consume them. To do this, you will have to create a FIFO queue and then route your device’s data to the queue.

In the Data menu, go to the FIFO tab and click on the add a FIFO queue button In the pop-in enter a name myFifo for your FIFO queue, then press Register button: the newly created FIFO queue myFifo is now listed.

landing

The FIFO queue is ready to persist data. To make your device’s data enter the queue, you have to route them to the queue. More information about routing in the section FIFO publish action.

Future messages sent by your device will be stored in the FIFO queue until an MQTT client subscribes to the queue.

The "application" mode purpose is to retrieve messages available in your FIFOs.

Available MQTT endpoints are described in the section Endpoints.

Beforehand, a connection must be established as follows :

  • clientId: ignored

  • username: application

  • password: a valid Live Objects API key with a BUS_R role

  • willRetain, willQoS, willFlag, willTopic, willMessage: ignored

Then a subscription to the following topic to consume data from your FIFO : "fifo/myFifo".

3.6.3. Tutorial video

3.7. Connect a device without a supported protocols

If you have a fleet of devices that do not support traditional protocols or that are connected to a custom backend, you can use the external connector mode:

  • Connect your specific devices with this mode

  • The external connector which uses the MQTT protocol, allows for all your data to be collected in a single place.

  • Monitor your devices connectivity

  • Configure your devices from Live objects platform

  • Receive command from Live Objects platform

  • Update your devices resource and configuration

4. Account Management and Access Control

4.1. Tenant account

A tenant account is the isolated space on Live Objects dedicated to a specific customer: every interaction between Live Objects and an external actor (user, device, client application, etc.) or registered entities (user accounts, API keys, etc.) is associated with a tenant account.

Live Objects ensures isolation between those accounts: you can’t access the data and entities managed in another tenant account.

Each tenant account is identified by a unique identifier: the tenant ID.

A tenant account also has a name, that should be unique.

4.2. User account

A User Account represents a user identity, that can access the Live Objects web portal.

A user account is identified by a login. A user account is associated with one or many roles. A user can authenticate on the Live Objects web portal using a login and password.

When user authentication request succeeds, a temporary API key is generated and returned, with same roles as the User account.

In case of too many invalid login attempts, the user account is locked out for a while.

For security purpose, a password must be at least 8 characters including at least 1 uppercase letter, 1 lowercase letter, 1 special character, 1 digit and 1 special characters.

4.3. API key

Interactive

A Live Objects API key is a secret that can be used by a device, an application, or a user to authenticate when accessing to Live Objects on the MQTT or HTTPS/REST interfaces. At least one API key must be generated. As a security measure, an API key can not be retrieved after creation (As describe in this section), .

An API key belongs to a tenant account: after authentication, all interactions will be associated only to this account (and thus isolated from other tenant accounts).

An API key can have zero, one or many Roles. These roles allows to restrict the operations that could be performed with the key.

An API key validity can be limited in time.

Creating a tenant account automatically attribute a "master" API key.

That API key is special: it can’t be deleted.

An API key can generate child-API keys that inherit (a subset of) the parent roles and validity period.

An API key can be restrained to one or more message queues:

  • If one or more message queues are selected, the API key can access only these queues.

  • If no message queue is selected, the API key has no restriction and can access any queue.

Thus, the API key can only be used in MQTT access limited to these selected message queues. This for example, makes it possible, after having oriented the right device to the right queue, to restrict access to the data of specific devices.

Usage:

  • In MQTT, clients must connect to Live Objects by using a valid API key value in the password field of the (first) MQTT « CONNECT » packet,

    • In case of unknown API key value, or invalid, the connection is refused.

    • On success, all messages published on this connection will be enriched with the API key id and roles.

  • In HTTPS, clients must specify a valid API key value as HTTP header X-API-Key for every request,

    • In case of unknown API key value, request is refused (HTTP status 403).

    • In case of invalid API key value, request is refused (HTTP status 401).

    • On success, all messages published due to this request will be enriched with the API key id and roles.

4.4. Role

A Role is attributed to an API key or User Account. It defines the privileges on Live Objects. A Role is attributed to an API key or User Account.

Important Notice : Some features are only available if you have subscribed to the corresponding offer, so you may have the proper roles set on your user but no access to some features because these features are not activated on your tenant account (check the tenant offer).

The currently available roles and their inclusion in Admin or User profiles:

Role Name Technical value Admin profile User profile Priviledges

API key

API_KEY_R

X

X

Read parameters and status of an API key.

API key

API_KEY_W

X

X

Create, modify, disable an API key.

User

USER_R

X

X

Read parameters and status of a user.

User

USER_W

X

Create, modify, disable a user.

Settings

SETTINGS_R

X

X

Read the tenant account custom settings.

Settings

SETTINGS_W

X

X

Create, modify tenant account custom settings.

Device

DEVICE_R

X

X

Read parameters and status of a Device management.

Device

DEVICE_W

X

Create, modify, disable a Device management, send command, modify config, update resource of a Device.

Device Campaign

CAMPAIGN_R

X

X

Read parameters and status of a massive deployment campaign on your Device Fleet.

Device Campaign

CAMPAIGN_W

X

Create, modify a campaign on your Device Fleet.

Data

DATA_R

X

X

Read the data collected by the Store Service or search into this data using the Search Service.

Data

DATA_W

X

Insert a data record to the Store Service. Minimum permission required for the API key of a device pushing data to Live Objects in HTTPS.

Data Processing

DATA_PROCESSING_R

X

X

Read parameters and status of an event processing rule or a Data decoder.

Data Processing

DATA_PROCESSING_W

X

Create, modify, disable an event processing rule or a Data decoder.

Bus Config

BUS_CONFIG_R

X

X

Read config parameters of a FIFO queue.

Bus Config

BUS_CONFIG_W

X

Create, modify a FIFO queue.

Bus Access

BUS_R

X

X

Read data on the Live Objects bus. Minimum permission for the API key of an application collecting data on Live Objects in MQTT(s).

Bus Access

BUS_W

X

X

Publish data on the Live Objects bus.

Bus Access

DEVICE_ACCESS

X

X

Role to set on a Device API key to allow only MQTT Device mode

Bus Access

CONNECTOR_ACCESS

X

X

Role to set on a external connector API key to allow only MQTT external connector mode

Audit Log

LOGS_R

X

X

Read the logs collected by the Audit Log service. This right allows users to use the Audit Log service as debugging tool.

5. Device and connectivity

The version 1 of the device APIs (/api/v1/deviceMgt) comes up with a brand new model of devices in Live Objects.

We have worked on providing unified representations whatever the technology that is used to connect the device to Live Objects using IP connectivity (MQTT, HTTP), LoRa® or SMS, while maintaining the access to each specific technology.

5.1. Principles

A device is a generic term that can designate an equipment (sensor, gateway) or an entity observed by equipments (ex: a building, a car).

5.2. Device description

A device description is a set of JSON documents that store a device identity information, a device state information, a metadata (definition, activity, alias) a device connectivity information for each device that you will connect to Live objects.

Each device description has 2 sections to describe the device representation :

  • Device identity.

  • Device interface representation.

5.2.1. Devices representation

5.2.1.1. Device identifier format

A device identity is represented by a unique identifier. This identifier must respect the following format:

urn:lo:nsid:{ns}:{id}

Where:

  • ns: your device identifier "namespace", used to avoid conflicts between various families of identifier

  • id: your device id

Should only contain alphanumeric characters (a-z, A-Z, 0-9) and/or any special characters amongst : - _ and must avoid $ ' ' * # / !| + and must respect the following regular expression: ^urn:lo:nsid:([\w-]{1,128}):([:\w-]{1,128})$ (with max 269 characters).

If your device is auto-provisioned (first connection), the device identifier namespace is automatically completed according to the "urn:lo:nsid" prefix (if not available) + the set of characters according the previous rule of regular expression.
5.2.1.2. Device object model

Depending on your connectivity interface, the device object model may have a dedicated "definition" section to describe the parameters of your interface (s).

Device object model overview:

Interactive

Device model in Json format

{
  "id": "urn:lo:nsid:sensor:temp001",
  "name": "mySensor001",
  "description": <<some description>>,
  "defaultDataStreamId": <<myStreamId>>,
  "activityState": <<monitoring the device>>
  "tags": ["Lyon", "Test"],
  "properties" : {
      "manufacturer": <<myManufacturer>>,
      "model": <<myModel>>
  },
  "group": {
      "id": <<id>>,
      "path": <<myPathId>>
  },
  "interfaces": [
        {
          "connector": <<myConnector>>,
          "nodeId": <<interface Id>>,
          "deviceId": "urn:lo:nsid:sensor:temp001",
          "enabled": <<true/false>>,
          "status": <<the status of the interface>>,
          "definition": {
                ........to learn more, see the "Device interface representation" section
          },
          "activity": {},
          "capabilities": {
                "command": {
                   "version" : <<versionNumber>>,
                   "available": <<true/false>>
                },
                "configuration": {
                   "available": <<true/false>>
                },
                "resources": {
                   "available": <<true/false>>
               }
           }
        }
    ],
    "created": <<date>>,
    "updated": <<date>>,
    "staticLocation": {
        "lat": <<Latitude value>>,
        "lon": <<Longitude value>>,
        "alt": <<Altitude value>>
    }
}

Device object model description:

JSON Params Description

id

device unique identifier (Cf. device identifier)

description

Optional. detailed description of the device

name

Optional. name of the device

defaultDataStreamId

default data stream id. Specify the streamId where the data will be store (Cf. "Manage your data stream" section).

tags

Optional. list of additional information used to tag device messages

properties

Optional. map of key/value string pairs detailing device properties

group

group to which the device belongs. The group is defined by its id and its path

interfaces

Optional. list of device network interfaces (Cf. interface object model)

created

creation date of the device

updated

last update date of the device

config

Optional. device configuration

firmwares

Deprecated device firmware versions (same value as "resources", available for compatibily reasons)

resources

Optional. device resource versions

activityState

Optional. device activity state aggregated from the activity processing service, the special state NOT_MONITORED means that the device is not targeted by any activity rule

staticLocation

Optional. the static location of device.

To avoid data personnal exposure, we strongly recommended to do not add a pesronnal and sensitive information in your tags and properties fields. This data are exposed and accessibles to Live Objects other services and components.
5.2.1.3. Device interface representation

An interface is a platform access. A device can have no, one or several interfaces, which represent different connectivities that the device could use to communicate with Live Objects. Each interface is associated to a protocol managed by Live Objects connector: LoRa®, SMS or MQTT. For the custom protocols, the devices must connected with external connector interface.

devices with single/multi connectivity

Interactive

Interface object model:

JSON Params Description

connector

connector identifier

nodeId

interface unique identifier

deviceId

Optional. device unique identifier

enabled

define if the interface is enabled or disabled

status

interface status

definition

interface definition. The definition depends on connector.

lastContact

Optional. lastContact is the last date of the last uplink from the device, in LoRa® connectivity, this field is also updated during a join request sent by the device.

activity

interface activity. The activity depends on connector.

capabilities

interface capabilities.

locations

Optional. list of last interface location.

created

registration date of the interface

updated

last update date of the interface

For more information on each connector definition, activity and status, see the appropriate section:

5.2.1.4. Interface status

Each interface has a status field which shows the state of the corresponding interface. The values are the same for all connectors, but each connector sets the status differently. The following table shows which statuses are supported, or will soon be supported by connectors.

Status \ Connector

LoRa®

MQTT

SMS

External connector

LwM2M

REGISTERED

ONLINE

OFFLINE

SLEEPING

CONNECTIVITY_ERROR

INITIALIZING

INITIALIZED

REACTIVATED

ACTIVATED

DEACTIVATED

Each interface has an enabled flag which allows or forbids an interface to connect and communicate with Live Objects. The enabled flag changes the interface’s status.

This flag can be set when creating the interface or updating the interface.

The following table shows a description of each technical value of the interface status.

Status Value Description

REGISTERED

The device has been registered in the network with the parameters specified when it was created. No uplink data has yet been received by the platform.

INITIALIZING

The network received a Join Request from the device

INITIALIZED

The network sent a Join Accept to the device

ACTIVATED

At least one uplink issued by the device was received by Live Objects (excluding MAC messages)

DEACTIVATED

The device has been deactivated in Live Objects. He can no longer communicate on the network (See the paragraph "Deactivate and reactivate a LoRa® device" and see the deactivation of the LwM2M device.

REACTIVATED

The device has been reactivated in Live Objects. Not being able to know a priori the state of the device at the time of the reactivation, the state will pass to "Activated" if a Join Request is received, or directly to "Activated" if an uplink is received.

CONNECTIVITY_ERROR

This status, rare, is displayed in case of problem on configuration of the equipment in the network. If this status appears, contact your support.

ONLINE (MQTT)

The MQTT connection of the device is active

ONLINE (LwM2M)

The LwM2M device is registered and active

SLEEPING (LwM2M)

The LwM2M device is in sleeping mode but the session is still active.

OFFLINE (MQTT)

The device has already connected at least once but its MQTT connection is inactive

OFFLINE (LwM2M)

The LwM2M device is deregistred or deactivated.

ONLINE (SMS)

The SMS device is activated at Live Objects level

OFFLINE (SMS)

The SMS device is deactivated at Live Objects level

5.2.1.5. Capabilities

Capabilities \ Connector

LoRa®

MQTT

SMS

External connector

LwM2M

Command

Configuration

Resource

Twin

Interface capabilities represent the Live Objects features compatibility.

  • Command : Compatibility with the generic command engine and API

  • Configuration : Compatibility with config update feature. MQTT connectivity only for now

  • Resource : Compatibility with resource update feature. MQTT connectivity only for now

  • Twin : Compatibility with the Live Objects twin service. LwM2M/CoAP connectivity only for now

5.2.1.6. Device static location

The static location is a set of a declared geographical coordinates values (longitude, latitude and altitude). Its section in the device object model must have the following format:

"staticLocation": {
        "lat": <<Latitude value>>,
        "lon": <<Longitude value>>,
        "alt": <<Altitude value>>
    }

This info is useful for stationary devices, or devices that are not sending location information to Live Objects.

This section can be created if setted during device provisioning.
POST /api/v1/deviceMgt/devices/<myDeviceId>
{
    "id": "<myDeviceId>",
    "description": "Device 123",
    "name": "My Device",
    "defaultDataStreamId": "MydefaultStream"
    "interfaces": [
        {
            "connector": "mqtt",
            "enabled": "true",
            "definition": {
                "clientId" : "<myDeviceId>",
                "encoding" : "myEncoding"
            }
        }
    ],
    "staticLocation": {
        "lat": <<Latitude value>>,
        "lon": <<Longitude value>>
    }
}

5.3. Device management basic

5.3.1. Register a device

5.3.1.1. Request

Endpoint:

POST /api/v1/deviceMgt/devices

HTTP Headers:

X-API-Key: <your API key>
Content-Type: application/json
Accept: application/json

Body:

JSON Params Description

id

device unique identifier (Cf. device object model)

tags

Optional. (Cf. device object model)

name

Optional. (Cf. device object model)

description

Optional. (Cf. device object model)

defaultDataStreamId

Optional. (Cf. device object model)

properties

Optional. (Cf. device object model)

group

Optional. (Cf. device object model)

interfaces

Optional. (Cf. device object model)

Devices can be registered with one or more chosen interfaces.

Currently, you can associate an SMS interface (Cf. register device with an SMS interface example) or a LoRa® interface (Cf. register device with a LoRa® interface example) with the devices. The other supported interfaces, the MQTT and External connector interfaces can be automatically registered during the first MQTT connection.

Example: Register a device without interface

POST /api/v1/deviceMgt/devices
{
  "id": "urn:lo:nsid:sensor:temp001",
  "tags": ["Lyon", "Test"],
  "name": "mySensor001",
  "description": "moisture sensor",
  "properties" : {
      "manufacturer": "Orange",
      "model": "MoistureSensorV3"
  },
  "group": {
      "path": "/france/lyon"
  }
}
5.3.1.2. Response

HTTP Code:

200 OK

Body:

Error case:

HTTP Code Error code message

400

GENERIC_INVALID_PARAMETER_ERROR

The submitted parameter is invalid.

403

GENERIC_OFFER_DISABLED_ERROR

The requested service is disabled in your offer settings. Please contact a sales representative.

403

GENERIC_ACTION_FORBIDDEN_ERROR

You do not have the required permissions to execute this action.

404

DM_GROUP_NOT_FOUND

Group not found

409

DM_INTERFACE_DUPLICATE

Interface already exists. Conflict on (connector/nodeId)

409

DM_DEVICE_DUPLICATE

Conflict on device id

Example: Register a device without interface

{
    "id": "urn:lo:nsid:sensor:temp001",
    "description": "moisture sensor",
    "name": "mySensor001",
    "defaultDataStreamId": "urn:lo:nsid:sensor:temp001",
    "tags": ["Lyon", "Test"],
    "properties": {
        "manufacturer": "Orange",
        "model": "MoistureSensorV3"
    },
    "group": {
        "id": "sWyaL2",
        "path": "/france/lyon"
    },
    "created": "2018-02-12T13:29:52.442Z",
    "updated": "2018-02-12T13:29:52.442Z"
}

5.3.2. List devices

5.3.2.1. Request

Endpoint:

GET /api/v1/deviceMgt/devices

Query parameters:

Name Description

limit

Optional. maximum number of devices in response. 20 by default.

offset

Optional. the number of entries to skip in the results list. 0 by default.

sort

Optional. sorting selection. Prefix with '-' for descending order. Supported value: id, name, group, created, updated,interfaces.status, interfaces.enabled, interfaces.lastContact. Example: ["urn","-creationTs"]"..

id

Optional. device id

groupPath

Optional. groupPath, Supported filters are → exact match : foo, group or subgroups : foo/*

groupId

Optional. filter list by groupId

name

Optional. device name, Supported filters are → contains : *foo*, end with foo : *foo, start with foo : foo*, exact match : "foo" or foo

tags

Optional. filter list by device tags

connectors

Optional. filter list by interface connector

fields

Optional. fields to return for each device. By default, information returned are id, name, group and tags. Supported value: name, description, group, tags, properties, interfaces, config, firmwares (deprecated), resources, defaultDataStreamId, activityState, created and updated.

interfaces.nodeId

Optional. Filter list by nodeId.

interfaces.status

Optional. Filter list by interface status.

interfaces.enabled

Optional. Filter list by interface enabled state.

property.{filterName}

Optional. Multiple filters, Example: devices?property.temperature=25&property.humidity=58…​

filterQuery

Optional. Device filter expression using RSQL notation. Supported device properties are tags, properties, groupId,groupPath, connector . Supported RSQL operators are ==, !=, =in=, =out=, =lt=, =le=, =gt=, =ge=, and, or.

HTTP Headers:

X-API-Key: <your API key>
Accept: application/json
X-Total-Count: <boolean>

For more info about X-Total-Count, see "API v1 paging" section.

Simple devices list request:

Get name, creation date and group of device having name starting with mySensor sorted by id descending.

GET /api/v1/deviceMgt/devices?name=mySensor*&sort=-id&fields=name,created,group

RSQL advanced devices list request:

Get id field only of devices matching following (RSQL filter url-encoded under) filterQuery: groupPath==/France;tags==demo;connector==lwm2m or (connector==x-connector)

For example, devices having /France as path and demo in tags, and (lwm2m or x-connector) as connector

GET /api/v1/deviceMgt/devices?fields=id&filterQuery=groupPath%3d%3d/France%3btags%3d%3ddemo%3bconnector%3d%3dlwm2m+or+(connector%3d%3dx-connector)
5.3.2.2. Response

HTTP Code:

200 OK

Body: List of device object model

JSON Params Description

id

device unique identifier

description

Optional. detailed description of the device

name

Optional. name of the device

defaultDataStreamId

Optional. default data stream Id of the device

tags

Optional. list of device tags

properties

Optional. properties of the device

group

Optional. group to which the device belongs

interfaces

Optional. list of device’s network interfaces

created

Optional. registration date of the device

updated

Optional. last update date of the device

config

Optional. device configuration

firmwares

Deprecated device firmware versions (same value as "resources", available for compatibily reasons)

resources

Optional. device resource versions

activityState

Optional. device activity state aggregated from the activity processing service, the special state NOT_MONITORED means that the device is not targeted by any activity rule

Simple devices list response example:

[
    {
        "id": "urn:lo:nsid:sensor:temp002",
        "name": "mySensor002",
        "group": {
            "id": "root",
            "path": "/"
        },
        "created": "2021-07-01T09:02:40.616Z"
    },
    {
        "id": "urn:lo:nsid:sensor:temp001",
        "name": "mySensor001",
        "group": {
            "id": "sWyaL2",
            "path": "/france/lyon"
        },
        "created": "2021-07-01T09:02:40.616Z"
    }
]

5.3.3. Get a device

5.3.3.1. Request

Endpoint:

GET /api/v1/deviceMgt/devices/<deviceId>

HTTP Headers:

X-API-Key: <your API key>
Accept: application/json

Example:

GET /api/v1/deviceMgt/devices/urn:lo:nsid:mqtt:myTest
5.3.3.2. Response

HTTP Code:

*200 OK*

Body:

Error case:

HTTP Code Error code message

400

GENERIC_INVALID_PARAMETER_ERROR

The submitted parameter is invalid.

401

UNAUTHORIZED

Authentication failure.

404

DM_DEVICE_NOT_FOUND

Device not found.

Example:

{
    "id": "urn:lo:nsid:sensor:temp002",
    "name": mySensor002",
    "description": "This device was auto registered by the connector [mqtt] with the nodeId [urn:lo:nsid:mqtt:myTest]",
    "group": {
        "id": "root",
        "path": "/"
    },
    "defaultDataStreamId": "urn:lo:nsid:sensor:temp002",
    "created": "2021-07-01T09:02:40.616Z",
    "updated": "2021-07-01T09:04:46.752Z",
    "activityState": "NOT_MONITORED",
    "interfaces": [
        {
            "connector": "mqtt",
            "nodeId": "urn:lo:nsid:mqtt:myTest",
            "enabled": true,
            "status": "OFFLINE",
            "lastContact": "2021-08-13T09:05:06.751Z",
            "capabilities": {
                "configuration": {
                    "available": false
                },
                "command": {
                    "available": false
                },
                "resource": {
                    "available": false
                },
                "twin": {
                    "available": false
                }
            },
            "activity": {
                "apiKeyId": "60508c314ca6b82d6d605b1e",
                "mqttVersion": 4,
                "mqttUsername": "json+device",
                "mqttTimeout": 60,
                "remoteAddress": "82.13.102.175/27659",
                "lastSessionStartTime": "2021-08-13T09:03:21.158Z",
                "lastSessionEndTime": "2021-08-13T09:04:06.750Z"
            },
            "created": "2021-07-01T09:02:40.615Z",
            "updated": "2021-07-01T09:04:46.752Z"
        }
    ]
}

5.3.4. Delete device

5.3.4.1. Request

Endpoint:

DELETE /api/v1/deviceMgt/devices/<deviceId>

HTTP Headers:

X-API-Key: <your API key>
Accept: application/json

Example:

DELETE /api/v1/deviceMgt/devices/urn:lo:nsid:sensor:temp001
5.3.4.2. Response

HTTP Code:

204 NO CONTENT

Error case:

HTTP Code Error code message

400

GENERIC_INVALID_PARAMETER_ERROR

The submitted parameter is invalid.

404

DM_DEVICE_NOT_FOUND

Device not found

5.4. Device interface management

5.4.1. Add an interface to a registered device

5.4.1.1. Request

Endpoint:

POST /api/v1/deviceMgt/devices/<deviceId>/interfaces

HTTP Headers:

X-API-Key: <your API key>
Content-Type: application/json
Accept: application/json

Body:

JSON Params Description

connector

connector id

enabled

define if the interface is enabled or disabled

definition

interface definition. The definition depends on connector (Cf. SMS interface definition or LoRa® interface definition).

Currently, you can only create an SMS or an LoRa® interface, MQTT interface will be auto-provisionned at the first connection.

Example: Create an SMS interface

POST /api/v1/deviceMgt/devices/urn:lo:nsid:sensor:temp001/interfaces
{
    "connector": "sms",
    "enabled": true,
    "definition": {
        "msisdn": "33601201201"
    }
}
5.4.1.2. Response

HTTP Code:

200 OK

Body:

Error case:

HTTP Code Error code message

400

GENERIC_INVALID_PARAMETER_ERROR

The submitted parameter is invalid.

403

GENERIC_OFFER_DISABLED_ERROR

The requested service is disabled in your offer settings. Please contact a sales representative.

404

DM_DEVICE_NOT_FOUND

Device not found

404

DM_CONNECTOR_UNAVAILABLE

Connector not found or unavailable

409

DM_INTERFACE_DUPLICATE

Interface already exists. Conflict on (connector/nodeId)

Example:

{
    "connector": "sms",
    "nodeId": "33601201201",
    "deviceId": "urn:lo:nsid:sensor:temp001",
    "enabled": true,
    "status": "ONLINE",
    "definition": {
        "msisdn": "33601201201"
    },
    "activity": {},
    "capabilities": {
        "command": {
            "version" : 1,
            "available": true
        },
        "configuration": {
            "available": false
        },
        "resources": {
            "available": false
        }
    },
    "created": "2018-03-02T15:54:33.943Z",
    "updated": "2018-03-02T15:54:33.943Z"
}

5.4.2. List device interfaces

5.4.2.1. Request

Endpoint:

GET /api/v1/deviceMgt/devices/<deviceId>/interfaces

HTTP Headers:

X-API-Key: <your API key>
Accept: application/json

Example:

GET /api/v1/deviceMgt/devices/urn:lo:nsid:sensor:temp001/interfaces
5.4.2.2. Response

HTTP Code:

200 OK

Body:

Error case:

HTTP Code Error code message

400

GENERIC_INVALID_PARAMETER_ERROR

The submitted parameter is invalid.

404

DM_DEVICE_NOT_FOUND

Device not found.

Example:

[
  {
    "connector": "sms",
    "nodeId": "33601201201",
    "enabled": true,
    "status": "ONLINE",
    "activity": {},
    "definition" : {
        "msisdn" : "33601201201",
        "serverPhoneNumber" : "12345"
    },
    "capabilities": {
        "command": {
            "version" : 1,
            "available": true
        },
        "configuration": {
            "available": false
        },
        "resources": {
            "available": false
        }
    }
  },
  {
    "connector": "mqtt",
    "nodeId": "urn:lo:nsid:sensor:temp001",
    "enabled": true,
    "status": "ONLINE",
    "lastContact": "2018-03-02T15:57:23.772Z",
    "activity" : {
        "apiKeyId" : "6c2c569d91b5f174f60bd73d",
        "mqttVersion" : 4,
        "mqttUsername" : "json+device",
        "mqttTimeout" : 60,
        "remoteAddress" : "217.0.0.0/44341",
        "lastSessionStartTime" : "2019-07-24T15:09:22.560Z",
        "lastSessionEndTime" : "2019-07-24T16:20:37.333Z",
        "security" : {
            "secured": true,
            "protocol": "TLSv1.2",
            "cipher": "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
            "clientCertAuthentication": true,
            "sniHostname": "mqtt.liveobjects.orange-business.com"
        }
    },
    "capabilities": {
        "command": {
            "version" : 1,
            "available": true ("false" if the device is "OFFLINE" or has not suscribed to the topic "dev/cmd")
        },
        "configuration": {
            "version" : 1,
            "available": true ("false" if the device is "OFFLINE" or has not suscribed to the topic "dev/cfg")
        },
        "resources": {
            "version" : 1,
            "available": true ("false" if the device is "OFFLINE" or has not suscribed to the topic "dev/rsc/upd")
        }
    },
    "firmwares" : { (same value as "resources", available for compatibility reasons)
        "MyFW" : "1.0.2"
    },
    "resources" : {
        "MyFW" : "1.0.2"
    }
  }
]

5.4.3. Get interface details

5.4.3.1. Request

Endpoint:

GET /api/v1/deviceMgt/devices/<deviceId>/interfaces/<interfaceId>

The interfaceId must respect the following format {connector}:{nodeId}.

HTTP Headers:

X-API-Key: <your API key>
Accept: application/json

Example:

GET /api/v1/deviceMgt/devices/urn:lo:nsid:sensor:temp001/interfaces/sms:33601201201
5.4.3.2. Response

HTTP Code:

200 OK

Body:

Error case:

HTTP Code Error code message

403

GENERIC_OFFER_DISABLED_ERROR

The requested service is disabled in your offer settings. Please contact a sales representative.

404

DM_CONNECTOR_UNAVAILABLE

Connector not found or unavailable

404

DM_INTERFACE_NOT_FOUND

Interface not found

404

DM_DEVICE_NOT_FOUND

Device not found

Example:

{
        "connector": "sms",
        "nodeId": "33601201201",
    "deviceId": "urn:lo:nsid:sensor:temp001",
        "enabled": true,
        "status": "ONLINE",
        "definition": {
            "msisdn": "33601201201"
        },
        "activity": {
            "lastUplink": {
                "timestamp": "2018-03-05T10:43:46.268Z",
                "serverPhoneNumber": "20259"
            }
        },
    "capabilities": {
        "command": {
            "version" : 1,
            "available": true
    },
        "configuration": {
            "available": false
        },
        "resources": {
            "available": false
        }
    },
    "created": "2018-03-05T10:20:06.404Z",
    "updated": "2018-03-05T10:20:06.408Z"
}

5.4.4. Update an interface

5.4.4.1. Request

Endpoint:

PATCH /api/v1/deviceMgt/devices/<deviceId>/interfaces/<interfaceId>

The interfaceId must respect the following format {connector}:{nodeId}.

HTTP Headers:

X-API-Key: <your API key>
Content-Type: application/json
Accept: application/json

Body:

JSON Params Description

deviceId

Optional. new device identifier

enabled

Optional. define if the interface is enabled or disabled

definition

Optional. new interface definition

Example:

PATCH /api/v1/deviceMgt/devices/urn:lo:nsid:sensor:temp001/interfaces/sms:33601201201
{
    "deviceId": "urn:lo:nsid:sensor:temp002",
    "enabled": "false",
    "definition": {
        "encoding": "myDecoder"
    }
}
5.4.4.2. Response

HTTP Code:

200 OK

Body:

Error case:

HTTP Code Error code message

404

DM_INTERFACE_NOT_FOUND

Interface not found

404

DM_DEVICE_NOT_FOUND

Device not found

Example:

{
    "connector": "sms",
    "nodeId": "33601201201",
    "deviceId": "urn:lo:nsid:sensor:temp002",
    "enabled": false,
    "status": "ONLINE",
    "definition": {
        "msisdn": "33601201201",
        "encoding": "myDecoder"
    },
    "activity": {
        "lastUplink": {
            "timestamp": "2018-03-05T10:43:46.268Z",
            "serverPhoneNumber": "20259"
        }
    },
    "capabilities": {
        "command": {
            "version" : 1,
            "available": true
        },
        "configuration": {
            "available": false
        },
        "resources": {
            "available": false
        }
    },
    "created": "2018-03-05T10:20:06.404Z",
    "updated": "2018-03-05T13:51:09.312Z"
}

5.4.5. Delete an interface

5.4.5.1. Request

Endpoint:

DELETE /api/v1/deviceMgt/devices/<deviceId>/interfaces/<interfaceId>

The interfaceId must respect the following format {connector}:{nodeId}.

HTTP Headers:

X-API-Key: <your API key>
Accept: application/json

Example:

DELETE /api/v1/deviceMgt/devices/urn:lo:nsid:sensor:temp001/interfaces/sms:33601201201
5.4.5.2. Response

HTTP Code:

204 NO CONTENT

Error case:

HTTP Code Error code message

403

GENERIC_OFFER_DISABLED_ERROR

The requested service is disabled in your offer settings. Please contact a sales representative.

404

DM_CONNECTOR_UNAVAILABLE

Connector not found or unavailable

404

DM_INTERFACE_NOT_FOUND

Interface not found

404

DM_DEVICE_NOT_FOUND

Device not found

5.5. Connectivity

5.5.1. LoRa® connector

5.5.1.1. Definitions

devEUI

The global end-device ID of the interface (for more information, see the chapter 6.2.1 of lora-alliance.org/wp-content/uploads/2020/11/lorawan1.0.3.pdf).

appEUI

The global application ID of the interface (for more information, see the chapter 6.1.2 of lora-alliance.org/wp-content/uploads/2020/11/lorawan1.0.3.pdf).

appKey

The application key of the interface (for more information, see the chapter 6.2.2 of lora-alliance.org/wp-content/uploads/2020/11/lorawan1.0.3.pdf).

activationType

OTAA: Over The Air Activation.

profile

profile of the Interface which represents the Class (A or C). Can be specific for an Interface (ex. LoRaMote devices) or generic (ex. LoRaWAN/DemonstratorClasseA or LoRaWAN/DemonstratorClasseC). Please refer to Orange LoRa® device reference. The API GET Profile allows to have the list of available profiles.

encoding

Optional. encoding type of the binary payload sent by the interface, the decoder must be registered first (Cf. "Decoding service" section).

connectivityOptions

connectivity options used for the interface. Supported options are ackUl and location.

connectivityPlan

connectivity plan to use for the interface.

Example:

{
    "devEUI": "0101010210101010",
    "profile": "Generic_classA_RX2SF9",
    "activationType": "OTAA",
    "appEUI": "9879876546543211",
    "appKey": "11223344556677889988776655443322",
    "connectivityOptions" : {
        "ackUl" : true,
        "location" : false
    },
    "connectivityPlan" : "orange-cs/CP_Basic"
}

Important Notice : Some features are only available if you have subscribed to the corresponding offer, so you may have the rights set on your tenant but no access to some features because these features are not activated on your tenant account (check the tenant offer).

If an option is applied to a device, it will be effective only if the option is allowed for the tenant. If both connectivityOptions and connectivityPlan are set, connectivityPlan will be selected. connectivityPlan should be used preferably at connectivityOptions but at least one of two shall be defined. connectivityPlan could be selected among list returned by the API LIST Connectivity plans .

5.5.1.2. Activity
JSON Params Description

lastActivationTs

Optional. last activation date of the interface

lastDeactivationTs

Optional. last deactivation date of the interface

lastSignalLevel

Optional. last signal level : this value is a signal level computed from last uplink. This value is the same as the one showed in the data message (Lora message signalLevel).

avgSignalLevel

Optional. average signal level : provides a level of the signal during the last uplinks transmitted by the device. The value is between 1 and 5 is computed from uplinks history (PER+SNR+ESP quality indicators aggregate). On frame counter reset, the uplinks history and average signal level are reset.

lastBatteryLevel

Optional. last battery level (for more information, see the chapter 5.5 of lora-alliance.org/wp-content/uploads/2020/11/lorawan1.0.3.pdf).

lastDlFcnt

Optional. last downlink frame counter

lastUlFcnt

Optional. last uplink frame counter

Example:

{
    "activity": {
        "lastActivationTs": "2018-03-19T13:02:13.482Z",
        "lastActivationTs": "2018-03-20T14:10:26.231Z",
        "lastSignalLevel": 5,
        "avgSignalLevel": 4,
        "lastBatteryLevel": 54,
        "lastDlFcnt": 7,
        "lastUlFcnt": 1
    }
}
5.5.1.3. Status

LoRa® supports the following statuses: REGISTERED, INITIALIZING, INITIALIZED, ACTIVATED, DEACTIVATED, REACTIVATED, CONNECTIVITY_ERROR. The following diagram shows how LoRa® connector sets interfaces' status. The consistency check referred in the diagram is an automatic periodic check that verifies the consistency of information between Live Objets and the LoRa® network provider, it can detect potential problems on an LoRa® interface.

Status state machine in LoRa® connector

Interactive

5.5.1.4. Examples
5.5.1.4.1. Register a device with LoRa® interface

For more explanation on device creation, please see Register a device section.

Request:

POST /api/v1/deviceMgt/devices
{
    "id": "urn:lo:nsid:lora:0101010210101010",
    "tags": ["Lyon", "Test"],
    "name": "myLoraSensor",
    "description": "device with LoRa interface",
    "properties" : {
        "manufacturer": "Orange",
        "model": "LoraSensor"
    },
    "interfaces": [
        {
            "connector": "lora",
            "enabled": true,
            "definition": {
                "devEUI": "0101010210101010",
                "profile": "Generic_classA_RX2SF9",
                "activationType": "OTAA",
                "appEUI": "9879876546543211",
                "appKey": "11223344556677889988776655443322",
                "connectivityOptions" : {
                    "ackUl" : true,
                    "location" : false
                },
                "connectivityPlan" : "orange-cs/CP_Basic"
            }
        }
    ],
    "group": {
        "id": "sWyaL2",
        "path": "/france/lyon"
    }
}

Response:

200 OK
{
    "id": "urn:lo:nsid:lora:0101010210101010",
    "name": "myLoraSensor",
    "description": "device with LoRa interface",
    "tags": [
        "Test",
        "Lyon"
    ],
    "properties": {
        "manufacturer": "Orange",
        "model": "LoraSensor"
    },
    "group": {
        "id": "sWyaL2",
        "path": "/france/lyon"
    },
    "interfaces": [
        {
            "connector": "lora",
            "nodeId": "0101010210101010",
            "enabled": true,
            "status": "REGISTERED",
            "definition": {
                "devEUI": "0101010210101010",
                "profile": "Generic_classA_RX2SF9",
                "activationType": "OTAA",
                "appEUI": "9879876546543211",
                "appKey": "11223344556677889988776655443322",
                "connectivityOptions" : {
                    "ackUl" : true,
                    "location" : false
                },
                "connectivityPlan" : "orange-cs/CP_Basic"
            }
        }
    ],
    "defaultDataStreamId": "urn:lo:nsid:lora:0101010210101010",
    "created": "2018-03-06T13:23:37.712Z",
    "updated": "2018-03-06T13:23:37.945Z"
}
5.5.1.4.2. Add a LoRa® interface to a registered device

For more information on interface addition, please see Add a interface section.

Request:

POST /api/v1/deviceMgt/devices/urn:lo:nsid:sensor:temp001/interfaces
{
    "connector": "lora",
    "enabled": true,
    "definition": {
        "devEUI": "0202020220202020",
        "profile": "Generic_classA_RX2SF9",
        "activationType": "OTAA",
        "appEUI": "4573876546543211",
        "appKey": "11113344556677889988776655443322",
        "connectivityOptions" : {
            "ackUl" : true,
            "location" : false
        },
        "connectivityPlan" : "orange-cs/CP_Basic"
    }
}

Response:

201 CREATED
{
    "connector": "lora",
    "nodeId": "0202020220202020",
    "deviceId": "urn:lo:nsid:sensor:temp001",
    "enabled": true,
    "status": "REGISTERED",
    "definition": {
        "devEUI": "0202020220202020",
        "activationType": "OTAA",
        "profile": "Generic_classA_RX2SF9",
        "appEUI": "4573876546543211",
        "connectivityPlan" : "orange-cs/CP_Basic"
    },
    "activity": {},
    "created": "2018-03-06T13:37:31.397Z",
    "updated": "2018-03-06T13:37:31.397Z"
}
5.5.1.4.3. List LoRa® connectivity plans

A connectivity plan defines the interface capabilities and parameters that are needed by the network for access service. These information elements shall be provided by the manufacturer.

5.5.1.4.4. Request

Endpoint:

GET /api/v1/deviceMgt/connectors/lora/connectivities

HTTP Headers:

X-API-Key: <your API key>
Accept: application/json
5.5.1.4.5. Response

HTTP Code:

200 OK

Body:

[ {
  "id" : "orange-cs/CP_Basic",
  "name" : "CP_Basic",
  "parameters" : {
    "nbTransMax" : 3,
    "location" : false,
    "ackUl" : false,
    "sfMax" : 12,
    "sfMin" : 7,
    "nbTransMin" : 1
  }
}, {
  "id" : "orange-cs/CP_ACK",
  "name" : "CP_ACK",
  "parameters" : {
    "nbTransMax" : 3,
    "location" : false,
    "ackUl" : true,
    "sfMax" : 12,
    "sfMin" : 7,
    "nbTransMin" : 1
  }
} ]
HTTP Code Error code message

403

4030

Service is disabled. Please contact your sales entry point.

5.5.1.4.6. Get LoRa® interfaces profiles

An interface-profile defines the interface capabilities and boot parameters that are needed by the network for access service. These information elements shall be provided by the manufacturer.

The profile of the interface which represents the Class (A or C). Can be specific for an Interface (ex. LoRaMote devices) or generic (ex. LoRaWAN/DemonstratorClasseA or LoRaWAN/DemonstratorClasseC). Please refer to Orange LoRa® device reference. The API GET profiles allows to have the list of available profiles.

5.5.1.4.7. Request

Endpoint:

GET /api/v1/deviceMgt/connectors/lora/profiles

HTTP Headers:

X-API-Key: <your API key>
Accept: application/json
5.5.1.4.8. Response

HTTP Code:

200 OK

Body:

[ "JRI", "DP_Generic_AS923_ClassA", "ERCOGENER_EG-IoT", "Sensing_Labs_T_IP68", "ESM 5k ELSYS Class A", "NETVOX_R711_AS923_ClassA", "Connit Pulse", "OCEAN_OBR-L", "ATIM Class A", "Adeunis RF Demonstrator_US_915", "DECENTLAB_DLR2-EU868", "DIGITAL_MATTER_EU868"]

Error case:

HTTP Code Error code message

403

4030

Service is disabled. Please contact your sales entry point.

5.5.2. SMS connector

5.5.2.1. Definitions

msisdn

device msisdn. Number uniquely identifying a subscription in a Global System for Mobile communications.

serverPhoneNumber

Optional. server phone number. Must be defined in the offer settings.

encoding

Optional. name of the decoder that will be used to decode received SMSs, the decoder must be registered first (Cf. "Decoding service" section).

{
    "msisdn": "33601201201",
    "serverPhoneNumber": "20259",
    "encoding": "myDecoder"
}

Msisdn is an international phone number : 6..15 digits starting with country code (ex. '33') and without international prefix (ex. '00').

Dummy examples of phone numbers:

  • Belgium: 32654332211

  • France: 33654332211

  • Spain: 34654332211

  • Romania: 40654332211

  • Slovakia: 421654332211

5.5.2.2. Eligible cellular subscriptions for SMS connectivity

To send and receive SMS messages to/from a device using an SMS interface, this device must have a cellular subscription from the following operators :

  • Orange France

  • Orange Poland

  • Orange Romania

  • Orange Slovakia

  • Orange Spain

5.5.2.3. Activity
JSON Params Description

lastUplink

Optional. last uplink date of the interface

lastDownlink

Optional. last downlink date of the interface

lastUplink and lastDownlink have the following format:

JSON Params Description

timestamp

date of the activity

serverPhoneNumber

server phone number used

Example:

{
    "activity": {
      "lastUplink" : {
        "timestamp" : "2020-09-07T14:50:04.352Z",
        "serverPhoneNumber" : "+3320259"
      },
      "lastDownlink" : {
        "timestamp" : "2020-09-07T14:42:24.180Z",
        "serverPhoneNumber" : "20259"
      }
    }
}
5.5.2.4. Status

The SMS connector supports the following statuses describes in interface status. When an SMS interface is created, its status is set to ONLINE and it will not change. When an SMS interface is disabled, its status is set to DEACTIVATED.

5.5.2.5. Examples
5.5.2.5.1. Register a device with an SMS interface

For more information on device creation, please see Register a device section.

Request:

POST /api/v1/deviceMgt/devices
{
    "id": "urn:lo:nsid:sensor:temp002",
    "tags": ["Lyon", "Test"],
    "name": "mySensor002",
    "description": "moisture sensor",
    "properties" : {
        "manufacturer": "Orange",
        "model": "MoistureSensorV3"
    },
    "interfaces": [
        {
            "connector": "sms",
            "enabled": true,
            "definition": {
                "msisdn": "33600000001",
                "serverPhoneNumber" : "20259"
            }
        }
    ],
    "group": {
        "id": "sWyaL2",
        "path": "/france/lyon"
    }
}

Response:

200 OK
{
    "id": "urn:lo:nsid:sensor:temp002",
    "name": "mySensor002",
    "description": "moisture sensor",
    "tags": [
        "Test",
        "Lyon"
    ],
    "properties": {
        "manufacturer": "Orange",
        "model": "MoistureSensorV3"
    },
    "group": {
        "id": "sWyaL2",
        "path": "/france/lyon"
    },
    "interfaces": [
        {
            "connector": "sms",
            "nodeId": "33600000001",
            "enabled": true,
            "status": "ONLINE",
            "definition": {
                "msisdn": "33600000001",
                "serverPhoneNumber" : "20259"
            }
        }
    ],
    "defaultDataStreamId": "urn:lo:nsid:sensor:temp002",
    "created": "2018-03-06T11:30:42.777Z",
    "updated": "2018-03-06T11:30:42.819Z"
}
5.5.2.5.2. Add an SMS interface to a registered device

For more information on interface addition and example with SMS interface, please see Add a interface section.

Request:

POST /api/v1/deviceMgt/devices/urn:lo:nsid:sensor:temp001/interfaces
{
    "connector": "sms",
    "enabled": true,
    "definition": {
      "msisdn": "33600000001",
      "serverPhoneNumber" : "20259"
    }
}

Response:

201 CREATED
{
    "connector": "sms",
    "nodeId": "33600000001",
    "deviceId": "urn:lo:nsid:sensor:temp001",
    "enabled": true,
    "status": "ONLINE",
    "definition": {
      "msisdn": "33600000001",
      "serverPhoneNumber" : "20259"
    },
    "activity": {},
    "created": "2018-03-06T13:37:31.397Z",
    "updated": "2018-03-06T13:37:31.397Z"
}

5.5.3. MQTT connector

For information about MQTT interface and messages that your device can send or receive, please refer to the MQTT device mode.

5.5.3.1. Definition

clientId

device clientId used in mqtt MQTT device mode.

encoding

Optional. name of the decoder that will be used to decode data received from this interface. It will override 'metadata.encoding' value from this device’s data messages. The decoder must be registered first (Cf. "Decoding service" section).

{
    "clientId" : "mydevice_001",
    "encoding" : "myEncoding_v1"
}
5.5.3.2. Activity
JSON Params Description

apiKeyId

Optional. id of the API KEY used for the last device connection

mqttVersion

Optional. mqtt version used by the device mqtt client

mqttUsername

Optional. mqtt username used by the device mqtt client

mqttTimeout

Optional. mqtt timeout configured by the device mqtt client

remoteAddress

Optional. public IP address of the device mqtt client

lastSessionStartTime

Optional. last mqtt session start date

lastSessionEndTime

Optional. last mqtt session end date

security

security information

security has the following format:

JSON Params Description

secured

is (or was) a security protocol used

protocol

Optional. security protocol used

cipher

Optional. cipher suite used

clientCertAuthentication

Optional. is (or was) client certificate authentication used

sniHostname

Optional. hostname provided by the Server Name Indication extension

Example:

{
    "activity" : {
      "apiKeyId" : "5de8d14085a455f5c8525655",
      "mqttVersion" : 4,
      "mqttUsername" : "json+device",
      "mqttTimeout" : 60,
      "remoteAddress" : "217.167.1.65/61214",
      "lastSessionStartTime" : "2020-08-18T15:32:33.510Z",
      "lastSessionEndTime" : "2020-08-18T15:48:51.488Z",
      "security" : {
        "secured": true,
        "protocol": "TLSv1.2",
        "cipher": "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
        "clientCertAuthentication": true,
        "sniHostname": "mqtt.liveobjects.orange-business.com"
      }
    }
}
5.5.3.3. Status

MQTT connector supports the ONLINE, OFFLINE, REGISTERED and DEACTIVATED statuses. The following diagram shows how the MQTT connector sets interfaces' status.

Status state machine in MQTT connector

Interactive

5.5.3.4. Examples
5.5.3.4.1. Register a device with an MQTT interface

For more information on device creation, please see Register a device section.

Request:

POST /api/v1/deviceMgt/devices

{
    "id": "urn:lo:nsid:mqtt:mydevice_001",
    "tags": ["Lyon", "Test"],
    "name": "mySensor002",
    "description": "moisture sensor",
    "properties" : {
        "manufacturer": "Orange",
        "model": "MoistureSensorV3"
    },
    "interfaces": [
        {
            "connector": "mqtt",
            "enabled": true,
            "definition": {
                "clientId" : "mydevice_001"
            }
        }
    ],
    "group": {
        "id": "sWyaL2",
        "path": "/france/lyon"
    }
}

Response:

200 OK
{
    "id": "urn:lo:nsid:mqtt:mydevice_001",
    "name": "mySensor002",
    "description": "moisture sensor",
    "tags": [
        "Test",
        "Lyon"
    ],
    "properties": {
        "manufacturer": "Orange",
        "model": "MoistureSensorV3"
    },
    "group": {
        "id": "sWyaL2",
        "path": "/france/lyon"
    },
    "interfaces": [
        {
            "connector": "mqtt",
            "nodeId": "mydevice_001",
            "enabled": true,
            "status": "REGISTERED",
            "definition": {
                "clientId" : "mydevice_001"
            }
        }
    ],
    "defaultDataStreamId": "urn:lo:nsid:mqtt:mydevice_001",
    "created": "2018-03-06T11:30:42.777Z",
    "updated": "2018-03-06T11:30:42.819Z"
}

5.5.4. LwM2M/CoAP Connector

Based on the LwM2M protocol, this connector implements the LwM2M connectivity based on the CoAP messaging protocol.

5.5.4.1. LwM2M interface representation

In addition to the unified representation of Live Objects interfaces, the LwM2M interface has specific fields that can provide information specific to LwM2M devices. :

Interactive

5.5.4.2. Definition

This section contains all security credentials used by the LWM2M device.

"definition": {
    "endpointName": "My_Device_End_Point_Name",
    "security": {
        "mode": "PSK",
        "pskInfo": {
            "identity": "My_PSK_Identity"
        }
    },
    "bootstrap": {
        "managed": "false"
    }
}
Json Params Description

endpointName

Unique identifier of the LWM2M interface.

security.mode

The security mode. Example: "PSK" for Pre-Shared Key mode. The security mode "PSK" for DTLS Pre-Shared Key is currently the only supported security mode.

security.pskInfo.identity

The Pre-Shared key (PSK) identity.

security.pskInfo.secret

The Pre-Shared key (PSK) secret.

bootstrap.managed

Whether the LiveObjects Bootstrap server is allowed to automatically provision information in the interface definition (e.g. the security section) or not. If enabled, the 'security' section must not be set manually.

5.5.4.3. Activity

The activity item provides a data on the connectivity as the device is active (or inactive) on the network and its interact with Live Objects connector.

"activity": {
    "lwm2mVersion": "1.1",
    "remoteAddress": "190.92.12.113",
    "remotePort": 59436,
    "queueMode": false,
    "bindings": [
        "U"
    ],
    "lastRegistrationDate": "2022-02-16T09:08:26.995Z",
    "registrationLifetime": 300,
    "lastUpdateDate": "2022-02-16T09:17:17.301Z",
    "lastBootstrapProvisioningDate": "2022-02-16T09:08:23.621Z"
}
Json Params Description

lwm2mVersion

Supported LwM2M protocol version.

remoteAddress

Used in the IP connections, the IP adress of the device wich have been registered on the LwM2M Live Objects service.

remotePort

Used port.

lastRegistrationDate

Last registration date.

registrationLifetime

Max duration of registered status of the interface. The lifetime is set by LwM2M device connector, when expires, the device is automatically deregistered and the connector change the interface status to OFFLINE. The value is expressed in seconds and can be announced by the the device during the registering (by default : value = 300 seconds).

queueMode

Bolean to set the max of the lifetime timeout before the device go to the sleeping status. This parmeter is set to false, only the the devices with the queuing mode can have the queueMode setted to true.

bindings

List of the network/transport protocols binding supported by the device (Only UDP ="U") will be supported until now.

lastUpdateDate

Last update date of the LwM2M interface parameters.

lastBootstrapProvisioningDate

the last time the device definition was updated by the LiveObjects Bootstrap server (only if bootstrap.managed is true in the interface definition).

5.5.4.4. Status

The LwM2M device interface can supports the following statuses :

Status Description

REGISTERED

The lwm2m interface is registered on LiveObjects, and LwM2M connector is waiting for connection from the device. The Capability TWIN is set to FALSE (device Twin is added at the time as the interface is created)

ONLINE

The lwm2m interface is connected to LwM2M connector and is in active listening. The TWIN capability is set to TRUE.

SLEEPING

The LwM2M interface is connected to LwM2M connector but is no longer in active listening (PSM = Power Saving Mode, used if QueueMode supported by the device).

OFFLINE

The LwM2M interface is disconnected and the LwM2M connector is waiting for the next connection request. The twin capability is set to FALSE.

DEACTIVATED

The LwM2M interface was deactivated by the user.

The following diagram shows how LwM2M connector sets interfaces' status.

Interactive

5.5.4.5. Examples
5.5.4.5.1. Create a LwM2M device

In order to provision a CoAP identity to connect your device, you will have to use the dedicated REST API as described in a following section.

When you need to create a new device, you must use the same way to create every type of Live Objects devices. The LwM2M interface is specific, so you can provision it by following this way:

Request

Endpoint:

POST /api/v1/deviceMgt/devices

HTTP Headers:

X-API-Key: <your API key>
Content-Type: application/json
Accept: application/json
{
    "id": "urn:lo:nsid:lwm2m:test12",
    "name": "Lwm2m device",
    "description": "device for test",
    "defaultDataStreamId": "urn:lo:nsid:lwm2m:test13Stream",

    "interfaces": [
        {
            "connector": "lwm2m",
            "enabled": "true",
            "definition": {
                "endpointName": "urn:lo:lwm2m:my_endpoint123",
                "security": {
                    "mode": "PSK",
                    "pskInfo": {
                        "identity": "test_lwm2m_id2",
                        "secret" : "my_psk_secret"
                    }
                }
            }
        }
    ]

}
Refer to definition to learn more about the definition section fields. The credentials endpointName, identity and secret are mandatory.

Body:

JSON Params Description

id

device unique identifier (Cf. device object model)

tags

Optional. (Cf. device object model)

name

Optional. (Cf. device object model)

description

Optional. (Cf. device object model)

defaultDataStreamId

Optional. (Cf. device object model)

properties

Optional. (Cf. device object model)

group

Optional. (Cf. device object model)

interfaces

Optional. (Cf. device object model)

Devices can be registered with one or more chosen interfaces. It mean that the LwM2M device can have other connectivity (MQTT, SMS, Lora or External connector)

Response

{
    "id": "urn:lo:nsid:lwm2m:test12",
    "name": "Lwm2m device",
    "description": "device for test",
    "tags": [],
    "properties": {},
    "group": {
        "id": "root",
        "path": "/"
    },
    "interfaces": [
        {
            "connector": "lwm2m",
            "nodeId": "urn:lo:lwm2m:my_endpoint123",
            "enabled": true,
            "status": "REGISTERED",
            "definition": {
                "endpointName": "urn:lo:lwm2m:my_endpoint123",
                "security": {
                    "mode": "PSK",
                    "pskInfo": {
                        "identity": "test_lwm2m_id2"
                    }
                }
            },
            "capabilities": {
                "configuration": {
                    "available": false
                },
                "command": {
                    "available": false
                },
                "resource": {
                    "available": false
                },
                "twin": {
                    "available": false,
                    "version": 1
                }
            },
            "activity": {},
            "created": "2022-02-17T13:21:52.838Z",
            "updated": "2022-02-17T13:21:52.838Z"
        }
    ],
    "defaultDataStreamId": "urn:lo:nsid:lwm2m:test13Stream",
    "created": "2022-02-17T13:21:52.831Z",
    "updated": "2022-02-17T13:21:52.874Z",
    "activityState": "NOT_MONITORED"
}

The twin capability is automatically loaded by the service but not operational until the first device connection.

For the security raisons, the value of the PSK key is deliberately hidden.

From this moment and after the complete provisioning of the LwM2M interface with the twin capability, the device can perform a register operation.

5.5.4.5.2. Create a LwM2M device managed by the LiveObjects Bootstrap server

If your device is managed by the LiveObjects LwM2M Bootstrap server, the security info will be automatically provisioned by the Bootstrap server during the bootstrap process. To allow this, the device must be created with the bootstrap.managed parameter set to true.

Request

Endpoint:

POST /api/v1/deviceMgt/devices

HTTP Headers:

X-API-Key: <your API key>
Content-Type: application/json
Accept: application/json
{
    "id": "urn:lo:nsid:lwm2m:test12",
    "name": "Lwm2m device managed by Bootstrap",
    "description": "device for test",
    "defaultDataStreamId": "urn:lo:nsid:lwm2m:test13Stream",
    "interfaces": [
        {
            "connector": "lwm2m",
            "enabled": "true",
            "definition": {
                "endpointName": "urn:lo:lwm2m:my_endpoint123",
                "bootstrap": {
                    "managed": true
                }
            }
        }
    ]
}
5.5.4.5.3. Checking the LwM2M interface

Endpoint:

GET /api/v1/deviceMgt/devices/my_device_id/interfaces

HTTP Headers:

X-API-Key: <your API key>
Content-Type: application/json
Accept: application/json
[
    {
        "connector": "lwm2m",
        "nodeId": "urn:lo:lwm2m:my_endpoint123",
        "enabled": true,
        "status": "REGISTERED",
        "definition": {
            "endpointName": "urn:lo:lwm2m:my_endpoint123",
            "security": {
                "mode": "PSK",
                "pskInfo": {
                    "identity": "test_lwm2m_id2"
                }
            }
        },
        "capabilities": {
            "configuration": {
                "available": false
            },
            "command": {
                "available": false
            },
            "resource": {
                "available": false
            },
            "twin": {
                "available": false,
                "version": 1
            }
        },
        "activity": {},
        "created": "2022-02-17T13:21:52.838Z",
        "updated": "2022-02-17T13:21:52.838Z"
    }
]

5.5.5. External connector

When you will connect devices that can not use a native connectivity in Live Objects (MQTT, LoRa®, SMS, COAP/LWM2M), you can use this API with the MQTT protocol and the external connector interface to connect and manage your devices. The protocol adapters (MQTT ⇐⇒ proprietary protocol) must be developed and maintained by the client.

The external connector mode purpose is to :

  • publish data and devices status

  • manage devices commands : subscribe to command requests and publish command responses

Typically, use this mode when you want to connect your back-end service (where your devices are connected to) to Live Objects.

"Connector" mode usage

Interactive

5.5.5.1. Definition

nodeId

the external connector’s id of the device. This is the shared id with Live Objects that will be used in all communication regarding this device.

encoding

Optional. name of the decoder that will be used to decode data received from this interface. It will override 'metadata.encoding' value from this device’s data messages. The decoder must be registered first (Cf. "Decoding service" section).

{
    "nodeId" : "myDevice_101",
    "encoding" : "myEncoding_v1"
}
5.5.5.2. Register a device with external connector interface

Before registering a device with an external connector interface, you must register a device. For more explanation on device creation, please see Register a device section.

Request:

POST /api/v1/deviceMgt/devices

{
  "id": "urn:lo:nsid:external:measures",
  "name": "sensor #12",
  "description": "MyDeviceMaker sensor #12",
  "defaultDataStreamId": "urn:lo:nsid:external:measures",
  "tags": [
    "demo",
    "sensor"
  ],
  "properties": {
    "manufacturer": "MyDeviceMaker, Inc.",
    "hwVersion": "2.0.1.7-us_64"
  },
  "interfaces": [
    {
      "connector": "x-connector",
      "enabled": true,
      "definition" : {
        "nodeId" : "myDevice1234"
      }
    }
  ]
}

Response:

{
  "id": "urn:lo:nsid:external:measures",
  "name": "sensor #12",
  "description": "MyDeviceMaker sensor #12",
  "tags": [
    "sensor",
    "demo"
  ],
  "properties": {
    "manufacturer": "MyDeviceMaker, Inc.",
    "hwVersion": "2.0.1.7-us_64"
  },
  "group": {
    "id": "root",
    "path": "/"
  },
  "interfaces": [
    {
      "connector": "x-connector",
      "nodeId": "myDevice1234",
      "enabled": true,
      "status": "REGISTERED",
      "definition": {
        "nodeId": "myDevice1234"
      },
      "capabilities": {
        "configuration": {
          "available": false
        },
        "command": {
          "available": false
        },
        "resource": {
          "available": false
        }
      },
      "created": "2020-02-06T09:31:44.461Z"
    }
  ],
  "defaultDataStreamId": "urn:lo:nsid:external:measures",
  "created": "2020-02-06T09:31:44.389Z",
  "updated": "2020-02-06T09:31:44.479Z",
  "activityState": "NOT_MONITORED"
}
When you register your device with an external connector interface, you must set a nodeId field in the definition section. The nodeId must be a string between 1 and 128 characters long, containing no spaces or special characters except :, - or _ . The nodeId must be unique.

When connected through this mode, this is the x-connector interface of the device which is used.

5.5.5.3. Auto-register

By default, the auto-provisioned deviceId for nodeId will be:

urn:lo:nsid:x-connector:{nodeId}

5.5.5.4. Status

The device behind the external connector interface supports only the REGISTERED, ONLINE and OFFLINE statuses. To learn more about how the device publish it’s statuses, see NodeStatus publication.

To learn more about how your external connector work, see "External connector" mode section.

Interactive

The REGISTERED status setted just after the registration step, once the new state is published, the REGISTERED status is no longer publishable in the connector/v1/nodes/{nodeId}/status topic.

6. MQTT protocol

Live Objects supports the MQTT protocol to enable bi-directional (publish/subscribe) communications between devices or applications and the platform.

MQTT must be used with encryption (TLS layer). It is possible to use MQTT without encryption in "device" mode but we strongly recommend a secured connection. MQTT can be used with or without encryption (TLS layer).

Live Objects also supports MQTT over secure WebSocket.

The Live Objects MQTT interface offers multiples "modes":

  • mode "device": dedicated only to device connection use-cases, based on simple JSON messages,

  • mode "connector": dedicated to application that will act as cloud gateway and transfer device status and data from devices toward Live Objects

  • mode "application": useful for your business application to retrieve data or event from Live Objects.

6.1. MQTT protocol support

MQTT protocol level supported is 3.1.1 (cf. MQTT Protocol Specification 3.1.1)

Live Objects acts as a standard MQTT message broker with some limitations:

  • the "will" functionality is not implemented, all "willXXX" flags and headers are not taken into account,

  • the "retain" functionality is not implemented,

  • the "duplicate" flag is not used,

  • the "clean session" flag is not used, the server always starts a new session.

Although Live Objects supports all control packets, QoS levels beyond the exchanges are not all fully guaranteed.

QoS definition guaranteed limitation

0

at most once delivery

yes

no

1

at least once delivery

yes

"duplicate" flag is not used,

2

exactly once delivery

no

same as QoS1


Live Objects has several application behaviors depending on the connection mode (user name) described in the following section. Currently Live objects supports 3 connection modes:

  • "device" mode used to communicate with a native MQTT device.

  • "external connector" mode is an API that allows communication with devices using other protocols not supported by Live Objects. To communicate with Live Objects, these devices are connected with a backend itself connected in "external connector" mode that can translate requests and responses (from / to) MQTT.

  • "application" mode with this mode, Live Objects provides an application mode to allow business applications to use the MQTT API.

6.1.1. Access topics restrictions

The first packet exchanged must be a MQTT CONNECT packet, sent from the client to the MQTT endpoint.

This packet must contain:

  • clientId: usage depends on the "mode", usually the deviceId in "device" mode

  • username: used to select a mode and encoding: (case sensitive)

  • password: an API Key with the mandatory roles depending of the connection mode

  • willRetain, willQoS, willFlag, willTopic, willMessage: ! Not taken into account !,

On reception, Live Objects validates the API key provided.

  • If the API key is valid, then Live Objects returns a MQTT CONNACK message with return code 0x00 Connection Accepted.

  • If the API key is not valid, then Live Objects returns a MQTT CONNACK message with return code 0x04 Connection Refused: bad username or password, and closes the TCP connection.

6.1.2. MQTT keep alive interval and Ping Req/Res

Live Objects answers to MQTT PINGREQ packets with MQTT PINGRES packets: this is a way for the MQTT client to avoid connection timeouts.

A Keep Alive value of zero (0) has the effect of turning off the keep alive mechanism. This means that, in this case, the Server is not required to disconnect the Client on the grounds of inactivity. Note that a Server is permitted to disconnect a Client that it determines to be inactive or non-responsive at any time, regardless of the Keep Alive value provided by that Client.

6.1.3. MQTT Subscribe

Once connected, the client can at any time subscribe and unsubscribe to/from topics.

Live Objects answers with a MQTT SUBACK packet only once all subscriptions could be resolved:

MQTT specification enforce that a MQTT SUBACK is returned even if actual subscription is impossible / forbidden. In Protocol 3.1 the MQTT client cannot be informed that it subscribed to an non existing Topic. In Protocol 3.1.1 the MQTT client will receive MQTT SUBACK with corresponding QoS of 0x80 (Failure).

Live Objects answers to MQTT UNSUBSCRIBE packet with a MQTT UNSUBACK packet only once existing subscriptions have been properly closed.

6.1.4. MQTT Disconnect

Live Objects closes the MQTT / TCP connection when receiving a MQTT DISCONNECT message.

6.1.5. TCP Disconnect

When the TCP connection closes (by client or broker), the broker will close the currently active subscriptions, etc.

6.2. Endpoints

Type Supported modes Endpoint Description

MQTT

device

mqtt://mqtt.liveobjects.orange-business.com:1883

Unsecure plain MQTT connection. Not recommended for production grade applications. Only available for prototyping on discover offers. Please reach out to us for specific use cases.

MQTTS

mqtts://mqtt.liveobjects.orange-business.com:8883

Secure MQTTS connection. Recommended for device mode. Supports both server and client authentications.

Secure Websocket

wss://mqtt.liveobjects.orange-business.com:443/mqtt

Secure MQTTS connection over Websocket. Supports server authentication only.

MQTTS

application, connector

mqtts://liveobjects.orange-business.com:8883

Secure MQTTS connection. Recommended. Supports both server and client authentications.

Secure Websocket

wss://liveobjects.orange-business.com:443/mqtt

Secure MQTTS connection over Websocket. Supports server authentication only.


Live Objects MQTTS endpoint supports the following cipher suites:

  • TLS_AES_256_GCM_SHA384 for TLS v1.3 only

  • TLS_AES_128_GCM_SHA256 for TLS v1.3 only

  • TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 for TLS v1.2 only

  • TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

  • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA

  • TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA

  • TLS_RSA_WITH_AES_128_GCM_SHA256 for TLS v1.2 only

  • TLS_RSA_WITH_AES_128_CBC_SHA

  • TLS_RSA_WITH_AES_256_CBC_SHA

TLS Server Name Indication (SNI) extension should be used for TLS connections. The SNI host_name field must match the target domain name. TLS connection is refused if host_name is invalid.

Mandatory: For TLS connections, MQTT devices MUST support:

  • At least TLS 1.2

  • Server Name Indication (SNI) extension

It is strongly recommended to use MQTTS for your production environment.

6.2.1. Legacy endpoints

Legacy endpoints liveobjects.orange-business.com are deprecated for device mode. TLS 1.0 and 1.1 on legacy endpoints are not supported. Legacy endpoints will be removed in the future

Type Modes Endpoint Description

MQTT

device

mqtt://liveobjects.orange-business.com:1883

Unsecure plain MQTT connection.

MQTTS

mqtts://liveobjects.orange-business.com:8883

Secure MQTTS connection. Supports both server and client authentications.

Websocket

wss://liveobjects.orange-business.com:443/mqtt

Unsecure plain MQTT connection over Websocket.

6.3. Secure your MQTT connection

6.3.1. Why use Secure MQTT protocol?

Using MQTT with TLS enabled provides privacy and data integrity between your devices/applications and Live Objects. It guarantees that your device/application is communicating with the authentic Live Objects platform, and it prevents a malicious third-party from eavesdropping or tampering. Using secure TLS communication is becoming a de facto standard when communicating over internet as more and more software / operating systems / Hardware refuse to communicate over non-encrypted protocols. Live Objects offers several levels of security that require adapted credentials according to the expected level of security.

6.3.2. MQTT security levels

3 security levels are available, for each one, the authentication is protected by TLS protocol and credentials, the client must have in its truststore and keystore the credentials below :

Authentication\ Credentials

Authentication level

clientId

API_KEY

Root CA certificate

Client certificate

MQTT

basic authentication

MQTTS server authentication

secured authentication

MQTTS server and client authentication

high secured authentication

6.3.3. MQTTS server authentication

A connection to the MQTT server secure endpoints requires that the MQTT clients maintain an up-to-date list of trusted root CA (Certificate Authority) certificates in order to seamlessly handle periodic server certificate updates.

6.3.3.1. Server Root CA certificates
domain name root certificate TLS supported version TLS mandatory options

mqtt.liveobjects.orange-business.com

DigiCert Global Root G2

TLS 1.2 , TLS 1.3

Server Name Indication (SNI)

liveobjects.orange-business.com

DigiCert Global Root CA

TLS 1.2 , TLS 1.3

Your device must have in its truststore the root CA DigiCert Global Root G2. Use the Live Objects (firmware) resource update feature to update the truststore.

Your application or external connector must have in its truststore the root CA DigiCert Global Root CA

  • Ensure that you can securely update your device or application software if security vulnerabilities are discovered.

  • Ensure that you have a way to update your root certificate list. Root CA are meant to be long-term certificates but Live Objects might have to change it.

  • Devices must be able to support at least two root CA certificates.

6.3.4. Go further with server and client authentication

Live Objects goes beyond server authentication and implements client authentication based on your own Certification Authority (CA). When enabled for a given API Key, Live Objects will:

  • make sure that only TLS with client authentication is made with this API key when used for MQTT connections

  • make sure that the client certificate has been signed by one of the CA certificates associated to the API key used by the device,

  • verify the identity of the device, by checking that client certificate’s Common Name (CN) matches the device id (in the MQTT client id). This last verification is done for MQTT “device” mode only. (i.e. not for MQTT “application” and “connector” mode)

Live Objects does not provide PKI services, but you can configure your Live Objects account to use your own PKI’s certificates. For the time being, a maximum limit of 10 certificates is set for a tenant.
6.3.4.1. Client certificat CA issuer requirements

Standard extensions

Basic constraints

A CA issuer certificate (which signed your client certificate) must include the basicConstraints value with the CA field set to TRUE. An end user certificate (device) must either set CA to FALSE or exclude the extension entirely.

You must check key usage extension of your CA issuer certificate, here are some common rules to consider :

Extension KeyUsage defined

In this case the KeyUsage extension must contains the permitted key usage with keyCertSign value. It can only be used to sign end user certificates and not further CAs. The end user certificates are used by the devices.

For example:

basicConstraints=CA:TRUE
keyUsage= keyCertSign <--

Extension KeyUsage not defined

Nothing to do. Your CA issuer can sign your devices certificates.

For example:

basicConstraints=CA:TRUE
without KeyUsage extension <--
Otherwise, in case where this rules are not respected, your CA certificate is rejected by Live Objects.
6.3.4.2. How to setup client authentication

The client authentication setup is done in 2 steps:

  • Make Live Objects aware of your Certification Authority (CA) by configuring the CA certificate which used to sign the devices certificates.

  • Check that your CA certificate meets standard requirements.

  • Associate that CA certificate with the API key used by your devices/external connector. This will force all communications to Live Objects using MQTT using that API key to be secured with a client certificate (or it will be rejected).

  • Generate a client certificate, signed with your CA certificate, with the MQTT Client ID as common name (CN) (for MQTT "device" mode only).

Client authentication is only available for MQTTS protocol. MQTT over secure websocket connection does not support client authentication.

1. Configure your Certification Authority’s intermediate certificate on Live Objects

Generate a key pair.

 openssl genrsa -out rootCA.key 2048

Use the key pair to generate your CA certificate.

 openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.pem

Configure your certificate on Live Objects:

POST /api/v0/certificates/ca
 {
   "certificate": "your pem formatted certificate",
   "comment": "my awesome intermediate CA certificate"
 }

This call will return an id for your certificate.

Only provision the CA’s intermediate certificate that directly signed the device Certificate Signing Request (CSR).
 {
  "id": "your_certificate_id"
 }
To get a JSON compliant string of your pem certificate you can use the command line tool jq : cat rootCA.pem | jq -R --slurp

2. Associate this certificate with an Api Key

POST /api/v0/apiKeys/{your-api-key-id}
 {
   "clientCert": {
     "caCertIds": [
       "your-certificate-id1",
       "your-certificate-id2"
     ],
     "required": true
   }
 }
Once a certificate is associated with an Api Key and clientCert.required=true client authenticated MQTTS connection will be mandatory, otherwise the MQTT(s)/websocket connection will be closed with a Bad username or password error.

3. Generate a client certificate for a device with id *your-device-id*

Create a key pair for the device.

 openssl genrsa -out deviceCert.key 2048

Create a certificate signing request from your key pair

 openssl req -new -key deviceCert.key -out deviceCert.csr

Enter the information when prompted

 Country Name (2 letter code) []:
 State or Province Name (full name) []:
 Locality Name (for example, city) []:
 Organization Name (for example, company) []:
 Organizational Unit Name (for example, section) []:
 Common Name (e.g. server FQDN or YOUR name) []: <--------- ENTER YOUR DEVICE URN HERE
 Email Address []:

Generate the device certificate by signing the CSR with your Certification Authority intermediate key.

 openssl x509 -req -in deviceCert.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out deviceCert.pem -days 365 -sha256

4. Try it

Try your newly configured MQTTS with client configuration by sending a new data on the dev/data topic. We will be using the node mqtt.js client:

mqtt publish -h "mqtt.liveobjects.orange-business.com" --port 8883 -i your-device-id -q 0 -u json+device -C mqtts -t dev/data -m '{"s": "myStreamId", "v": {"temp": 12}}' --key your-cert-private-key --cert your-cert.pem --ca liveObjects.ca.cert.pem -P your-api-key
Once a certificate is associated with an Api Key and clientCert.required=true client authenticated MQTTS connection and MQTTS endpoint usage will be mandatory (see how to use MQTTS).

6.4. Debug MQTT/MQTTS connection

Usual error codes returned by MQTT connector when the client try to connect Live Objects over MQTT protocol :

Authentication

Username (depending on your MQTT mode)

API_KEY (password)

Root CA issuer certificate

API key CA certificate

Client certificate (CN=ClientID)

Connack return code

MQTT (basic authentication/TLS)

bad

bad

none

none

none

0x04 bad credentials

MQTT (basic authentication/TLS)

bad

compliant

none

none

none

0x04 bad credentials

MQTT (basic authentication/TLS)

compliant

bad

none

none

none

0x04 bad credentials

MQTT (basic authentication)

compliant

compliant

none

none

none

0x00 accepted

MQTTS server authentication (TLS)

compliant

compliant

Bad, expired or missing

none

none

0x05 not authorized

MQTTS server authentication (TLS)

compliant

compliant

compliant

none

none

0x00 accepted

MQTTS server and client authentication

compliant

compliant

compliant

compliant

none

0x05 not authorized

MQTTS server and client authentication

compliant

compliant

compliant

compliant

CN =/= client ID

0x05 not authorized

MQTTS server and client authentication

compliant

compliant

compliant

compliant

bad certificate chain

0x05 not authorized

MQTTS server and client authentication

compliant

compliant

compliant

compliant

compliant

0x00 accepted

6.5. "Device" mode

In the "Device" mode, a single MQTT connection is associated with a specific device, and JSON messages can be exchanged to support various Device Management and Data features:

  • notifying of the device connectivity status,

  • notifying of the current device configuration and receiving configuration updates,

  • notifying of the list of current device "resources" (i.e. binary contents) versions, and receiving resource update requests,

  • receiving commands and responding to them,

  • receiving configuration update and responding to it,

  • sending data messages that will be stored.

Device and data management features

Interactive

6.5.1. Connection

When initiating the MQTT connection, to select the "Device" mode you must 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 to use a secured 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.

6.5.2. 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

6.5.3. 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.

6.5.4. Summary

Authorized MQTT actions for a device:

Direction

Topic

Description

Data message publication

publish to

dev/data

to publish a JSON data message

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.

6.5.5. Data message publication

6.5.5.1. JSON data publication

Data published by devices through MQTT will be processed by the Data enrichment logic.

To publish JSON data into Live Objects, 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>>,...]
}

Message fields:

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

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

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

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

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

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

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

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

  • provider : GPS, cellular or custom

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" ]
}
6.5.5.2. 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 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"
}

6.5.6. Configuration

6.5.6.1. 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
      }
   }
}
6.5.6.2. 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
}
6.5.6.3. 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.

6.5.7. Commands

6.5.7.1. 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
}
6.5.7.2. 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.

6.5.8. Resources

6.5.8.1. 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"
      }
   }
}
6.5.8.2. 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, to download an apply,

  • 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
}
6.5.8.3. 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
}
6.5.8.4. 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

This 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"
}

6.6. "External connector" mode

6.6.1. Connection

When initiating the MQTT connection, to select the "connector" mode you must use the following credentials:

  • clientId: any string between 1 and 128 characters long, containing no spaces or special characters except :, - or _ . The MQTT protocol indicates it must be unique per connection, but Live Objects does not enforce it.

  • username: connector (case sensitive)

  • password: a valid API Key with CONNECTOR_ACCESS role

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

You must use a secured connection (MQTTS port 8883). The MQTT non-secured connection is not supported for "external connector" mode.

6.6.2. Summary

In "connector" mode, you can manage following device actions:

  • NodeStatus: publish in Live Objects a NodeStatus to set the ONLINE/OFFLINE status of the device (i.e. the node) and its capabilities

  • DataMessage: publish in Live Objects a DataMessage sent by the device

  • Command: subscribe to command requests and publish command responses

  • Configuration: handle configuration request or report modifications of a configuration of a device

  • Resource: manage resource update request or report current resource of a device behind the external connector

Direction Topic Description

NodeStatus publication

Publish

connector/v1/nodes/{nodeId}/status

To publish a NodeStatus for a device

Data message publication

Publish

connector/v1/nodes/{nodeId}/data

To publish a device DataMessage (telemetry event) to Live Objects

Commands

Subscribe

connector/v1/requests/command

To subscribe to command requests for devices. Commands can be manage through HTTP APIs.

Publish

connector/v1/responses/command

To publish a device command response

Configurations

Publish

connector/v1/current/configuration

To send a report of an initial configuration of a device to Live Objects

Subscribe

connector/v1/requests/configuration

To be notified (from Live Objects) of a configuration update for a device

Publish

connector/v1/responses/configuration

To respond/acknoledge to a device configuration request

Resources

Publish

connector/v1/current/resource

To send a report of resources current versions (firmware versions) of a device to Live Objects

Subscribe

connector/v1/requests/resource

To be notified (from Live Objects) of a resource version ugrade request

Publish

connector/v1/responses/resource

To respond/acknoledge to a resource version update request

6.6.3. NodeStatus publication

A NodeStatus publication allows to set the ONLINE/OFFLINE status of the device and its capacity to receive or not command requests.

The topic to publish is: connector/v1/nodes/{nodeId}/status

If the nodeId in the publication topic is unknown by Live Objects, a device with this NodeStatus information will be auto-provisioned in the Device inventory.

If the nodeId is already declared for a device in the Device inventory, then this NodeStatus information will update the corresponding device state in the Device inventory.

The link between a DeviceId and a NodeId is described in the Device and connectivity chapter.

The payload of this publication should follow :

NodeStatus publication
{
    "status": "ONLINE",
    "capabilities": {
        "command": {
            "available": true
        },
        "configuration": {
            "available": true
        },
        "resource": {
            "available": true
        }
    },
    "lastContact": "2019-05-20T16:01:47Z",
    "sessionSequenceId": 1,
    "eventSequenceId": 3
}

Only the 'status' field is mandatory.

Field Description

status

(Mandatory). Either 'ONLINE' or 'OFFLINE'.

capabilities.command

(Optional). Define if the device is able to receive commands. If true, you will be able to send commands to this device using the HTTP API.

capabilities.configuration

(Optional). Define if the device is able to receive configuration update. If true, you will be able to send new configurations to this device using the HTTP API.

capabilities.resource

(Optional). Define if the device is able to receive resource update. If true, you will be able to send new resource update to this device using the HTTP API.

lastContact

(Optional). Should follow ISO-8601 format. Set the lastContact information that will be updated in DataManager.

sessionSequenceId

(Optional). If present, the event will be taken into account only if no previous event had a higher sessionSequenceId.

eventSequenceId

(Optional). If present, the event will be taken into account only if no previous event had a higher sessionSequenceId or eventSequenceId.

As messages are asynchronously handled by Live Objects, sessionSequenceId and eventSequenceId mechanism allows to enforce message ordering (only the last status message will be taken into account). If this ordering is mandatory for your application, you should set them. For a unique MQTT session, sessionSequenceId should remain identical; and you can use epoch milliseconds from your application server as eventSequenceId.

If the publication succeeds, Live Objects will acknowledge the message according to the QoS level.

If the publication fails (for ex. because the JSON is badly formatted), Live Objects will nevertheless acknowledge the message according to the QoS level, and an AuditLog message will be sent with failure details.

6.6.4. Messages publication as a device

A DataMessage publication in the "connector" mode allows to send a DataMessage on behalf of a specific device.

The topic to publish is: connector/v1/nodes/{nodeId}/data

The payload of this publication should follow :

DataMessage publication
{
    "streamId": "urn:lo:nsid:detector_A8:12435355",
    "timestamp": "2019-05-20T16:01:47Z",
    "model": "data_v0",
    "value": {
        "temperature" : 14.6,
                "battery" : 53,
                "messageAlert":"low battery"
    },
    "location": {
        "lat": 48.86667,
        "lon": 2.33333,
        "alt": 35.2,
        "accuracy": 12.3,
        "provider": "GPS"
    },
    "tags": [ "production", "london" ]
}
Field Description

streamId

(Optional). The streamId where the data will be stored in; and retrieved using the HTTP store API. If not set, the default streamId set for this device in the Device inventory will be used. Should not contain any of the following character : ' " \ ; { } ( )

timestamp

(Optional). Should follow ISO-8601 format. If not set, current timestamp will be used.

model

(Optional). Can not contains ' ' (space) or '.' (dot) character. Model is needed to be able to use the search APIs on fields inside the value object.

value

(Optional). JSON compliant object. No inner field name should contains '.' (dot) character.

location

(Optional). If set, geo-query will be available through search APIs.

tags

(Optional) List of additional information used to tag the DataMessage

If the publication succeeds, Live Objects will acknowledge the message according to the QoS level.

If the publication fails (for ex. because the JSON is badly formatted), Live Objects will nevertheless acknowledge the message according to the QoS level, and an AuditLog message will be sent with anomaly details.

6.6.4.1. Encoded DataMessage publication

In order to use the decoding capability of Live Objects, a DataMessage must contains additional 'value.payload' and 'metadata.encoding' fields :

Encoded DataMessage publication
{
    "value": {
        "payload": "000003F5000000DD"
    },
    "metadata": {
        "encoding": "twointegers"
    }
}
Field Description

value.payload

(Mandatory). Payload to decode. In case of binary content, HexBinary String representation of the payload to decode.

metadata.encoding

(Mandatory). Encoded format name, that should match the 'encoding' name of the decoder that can process this message.

All other fields of DataMessage (streamId, timestamp, location, tags…​) can also optionally be set in the encoded DataMessage.

An alternative is to set the encoding property in the x-connector device’s interface definition through DeviceManagement APIs.

6.6.5. Commands

You can refer to commands description to have insights on the devices commands workflow. Using external connector mode, the basics are:

  • once connected in external connector mode, subscribe to command requests

  • create a command targeting a specific device using HTTP APIs or the web portal

  • when this device is connected (publishing a NodeStatus message with a command capability set to true), this command request is published into subscribed topic connector/v1/requests/command

  • optionally, publish the device command response

  • the command status is updated, and can be retrieved using HTTP APIs.

6.6.5.1. Retrieve the command request

Your external connector will receive all command requests targeting your devices.

This command requests are created through Live Objects HTTP APIs; please see dedicated section to know more about command requests.

The topic to subscribe is: connector/v1/requests/command

The received message in the subscribed topic has this model:

Command request message
{
    "id": "0f1253df-9b34-4e97-8e1e-457317107271",
    "nodeId": "myDevice",
    "value": {
        "req": "on",
        "args": {
            "level": 75
        }
    },
    "ackMode": "APPLICATIVE"
}
Field Description

id

(Mandatory). Unique id of the command request. The command response will use this id to correlate request and response.

nodeId

(Mandatory). Define the request’s targeted nodeId.

value

(Optional). The command request value that have been set when created through the HTTP API (any JSON Object).

ackMode

(Mandatory). The acknowledgement mode of this command (set when the command is created through the HTTP API). Either NONE, NETWORK or APPLICATIVE.

If ackMode is NETWORK or APPLICATIVE, a command response with the request’s id should be published as described command response section in order to update the command’s status. In this MQTT 'connector' mode, NETWORK and APPLICATIVE ackModes lead to the same behaviour.

6.6.5.2. Response publication

In order to reply to a command request, your external connector should publish to the topic: connector/v1/responses/command.

Command response message
{
    "id": "0f1253df-9b34-4e97-8e1e-457317107271",
    "nodeId": "myDevice",
    "response": {
        "status": "ok",
        "message": {
            "level": 75
        }
    }
}
Field Description

id

(Mandatory). id of the command request that triggered this response.

nodeId

(Mandatory). the nodeId which has generated the response (should be the same as the one in the request).

response

(Optional). This JSON Object will be stored as the command response when retrieved through he HTTP API.

With this response, the command’s status will change to PROCESSED. And if there is other command requests in queue for this device, the next one will be published.

If the publication succeeds, Live Objects will acknowledge the message according to the QoS level.

If the publication fails (for ex. because the JSON is badly formatted), Live Objects will nevertheless acknowledge the message according to the QoS level, and an AuditLog message will be sent with failure details.

6.6.6. Configurations

You can refer to configuration description to have insights on the devices configuration workflow.

Using external connector mode, the basics regarding this feature are:

  • connect to Live Objects MQTT in external connector mode, subscribe to configuration requests on the following topic connector/v1/requests/configuration

  • connect the device (publish a NodeStatus message with a configuration capability set to true),

  • set requested configuration targeting a specific device behind your external connector using HTTP APIs or the web portal

  • a configuration request will be received on the topic you suscribed above

  • when configuration is set on the device, your external connector publishes a device configuration response to connector/v1/responses/configuration

  • the configurations are updated, and can be retrieved using HTTP APIs: liveobjects.orange-business.com/api/v1/deviceMgt/devices/{deviceId}/config

Also, a device can change its configuration by itself. To report a configuration change, your external connector must publish in connector/v1/current/configuration

6.6.6.1. Retrieve the configuration request

Your external connector will receive all configuration requests targeting your devices.

These configuration requests are created through Live Objects HTTP APIs or web portal. Please see dedicated section to know more about configuration requests.

The topic to subscribe is: connector/v1/requests/configuration

The received message on the subscribed topic has this model:

Configuration request message
{
        "nodeId": "9ea64eb7-a5b4-4573-86e3-b6d949dc55a3",
        "targetVersion": 363745365,
        "parameters": {
                "my_param1": {
                        "type": "UINT32",
                        "value": 8035095625792325998
                },
                "my_param2": {
                        "type": "FLOAT",
                        "value": 0.8862329945028716
                },
                "my_param3": {
                        "type": "BINARY",
                        "value": "WldGbE16QXdtRmlPV1pt"
                },
                "my_param4": {
                        "type": "INT32",
                        "value": 1101263487
                },
                "my_param5": {
                        "type": "STRING",
                        "value": "my config as a string"
                }
        }
}
Field Description

nodeId

(Mandatory). Define the request’s targeted nodeId.

targetVersion

(Mandatory). The configuration request version for all provided parameters

parameters

(Mandatory). A JSON object where each field is a parameter name and each value a ParameterValue object. This format is the same that is used by the HTTP APIs. See the our swagger.

6.6.6.2. Response publication

In order to reply to a configuration request, your external connector must publish in the topic: connector/v1/responses/configuration.

configuration request and configuration response have the same format. To acknowledge a configuration request on a specific parameter, the response must contain the same target version and value.

Configuration response message
{
        "nodeId": "9ea64eb7-a5b4-4573-86e3-b6d949dc55a3",
        "targetVersion": 363745365,
        "parameters": {
                "my_param1": {
                        "type": "UINT32",
                        "value": 8035095625792325998
                },
                "my_param2": {
                        "type": "FLOAT",
                        "value": 0.8862329945028716
                }
        }
}

With this response, "my_param1" and "my_param2" are acknowledged. It can be checked on the portal or with HTTP APIs.

If the publication succeeds, Live Objects will acknowledge the message according to the QoS level.

If the publication fails (for ex. because the JSON is badly formatted), Live Objects will nevertheless acknowledge the message according to the QoS level, and an AuditLog message will be sent with failure details.

6.6.6.3. Publish the current device configuration in Live Objects

In addition to these two topics described in the previous chapter, Live Objects allows your external connector to announce current configuration of a device.

The topic to publish is: connector/v1/current/configuration

The message format is the same than before, except that there is no targetVersion.

Current configuration message
{
        "nodeId": "9ea64eb7-a5b4-4573-86e3-b6d949dc55a3",
        "parameters": {
                "my_param4": {
                        "type": "INT32",
                        "value": 123
                },
                "my_param5": {
                        "type": "FLOAT",
                        "value": 0.45562329946543
                }
        }
}

6.6.7. Resources

You can refer to resource description to have more information on the device resources management workflow.

Using external connector mode, the basics regarding this feature are:

  • Connect to Live Objects using MQTTS in external connector mode

  • Connect the device (publish a NodeStatus message with a resource capability set to true)

  • Send to Live Objects the current version of each device resource by publishing on connector/v1/current/resource

  • Subscribe to resources update requests with the following topic connector/v1/requests/resource

  • In order to update a resource for a given device, set its target version with HTTP APIs or the web portal

  • A resource update request will be received on the topic you suscribed above

  • Download the resource with the given resource url

  • Update your device with the resource (firmware)

  • (opt) Inform Live Objects of failure of the update process. Publish a device resource update response to connector/v1/responses/resource

  • When your resource is updated, send to Live Objects the new version of each device resource. publish on connector/v1/current/resource

  • The resource update informations can be retrieved using HTTP APIs: liveobjects.orange-business.com/api/v1/deviceMgt/devices/{deviceId}/resources/updates

6.6.7.1. Be notified of the resources update request

Your external connector will receive all resources update requests targeting your devices.

These resources update requests are created through Live Objects HTTP APIs or web portal. Please see dedicated section to know more about resource update.

The topic to subscribe is: connector/v1/requests/resource

The received message on the subscribed topic has this model:

resource update request message
{
        "nodeId": "CfnpFC6r",
        "resourceId": "my_resource",
        "updateCorrelationId": "5fc0db74e4332f0001aadf0c",
        "sourceVersion": "1.0",
        "targetVersion": "2.0",
        "delivery": {
                "type": "HTTP_DELIVERY",
                "uri": "https://liveobjects.orange-business.com:443/dl/r7n2b87cc6t8l6pst2t7avg1h5",
                "md5": "6dcdc9dcef09d8571994ac1b712b34c0",
                "size": 1024
        }
}
Field Description

nodeId

(Mandatory). Define the request’s targeted nodeId.

resourceId

(Mandatory). The resource id

updateCorrelationId

(Mandatory). The correlation id for this specific resource update

sourceVersion

(Mandatory). The current version of the resource

targetVersion

(Mandatory). The target version for the resource

delivery

Informations needed for resource download

delivery.type

should be HTTP_DELIVERY

delivery.uri

Download URI

delivery.md5

signature (md5) of the raw (non Base64-encoded) resource file

delivery.size

file size in bytes

6.6.7.2. Resource update report publication

In order to send a report to Live Objects on the resource update process, your external connector must publish on the topic: connector/v1/responses/resource.

The response is optional but is useful when an error occurs during the update process in the device side. If the update succeeded in the device side, your external connector must publish the current resources of the device. See the next chapter.
resource update response message
{
        "nodeId": "HA0lQz8R",
        "updateCorrelationId": "5fc10d40e4332f0001aadf39",
        "status": "FAILED",
        "error": {
                "code": "myErrorCode",
                "details": "myErrorDetails"
        }
}
Field Description

nodeId

(Mandatory). Define the request’s targeted nodeId

updateCorrelationId

(Mandatory). The correlation id for this specific resource update (provided by the resource update request)

status

(Mandatory). Only the status "FAILED" is accepted.

error.code

(Optional) in case of failure, error code (String).

error.details

(Optional) in case of failure, error details (String).

The update process status can be retrieved with HTTP API, using Device management - Resources APIs

6.6.7.3. Publish the current device resources' versions in Live Objects

Live Objects allows your external connector to report the current resources' versions of a device. This can be done at any time. When a resource update is done on the device side (firmware update for instance), the device must report this new version in order to update the resource version declared on the Live Object platform.

The topic to publish is: connector/v1/current/resource

Current resource message
{
  "nodeId": "CLcl0F4b",
  "resources": {
    "my_specific_resource": {
      "version": "1.0"
    },
    "my_firmware": {
      "version": "3.2"
    }
  }
}
Field Description

nodeId

(Mandatory). Define the request’s targeted nodeId.

resources

(Mandatory). map of resource names. The "version" field value must be a "string"

6.7. "Application" mode

In addition to the 2 modes available for devices, the MQTT protocol can also be used for data exchange between a business application and Live Objects. In this mode, the protocol is used by a third party application which requires a reliable link with Live Objects.

Due to the specific use of this mode, it is subject to restrictions and security limitations..

To learn more about "application mode" using MQTTS protocol see.

7. LwM2M protocol

7.1. Introduction

LwM2M, for Lightweight Machine 2 Machine, is a communication protocol standard from the Open Mobile Alliance. It was designed specifically for remote device management and telemetry within the Internet of Things. Unlike MQTT, LwM2M fully specifies the application layer for device management and provides an extensive set of standard objects for telemetry data, enabling interoperability between objects and platforms from different vendors. LwM2M supports also optimized protocol headers and payload encodings to reduce bandwidth consumption and extend sensor’s battery lifetime.

Currently Live Objects LwM2M connector uses CoAPs for the message transfer by using IP connectivity and DTLS secure connections. In the future more connectivities and more security mechanisms will be available (TLS, OSCORE).

Live Objects implements 1.1 version of the protocol which includes the main features (the older version 1.0 of LwM2M protocol is also supported), in addition includes the specific features of device management and data management.

Live Objects provide the following features:

  • LwM2M standard features coming from the specification, which are the standardized interfaces between a lwm2m device and a lwm2m server (LiveObjects).

  • Higher Level features (mainly Device Twin) specific to LiveObjects which allows an advanced and industrial management of LwM2M devices and data, and which allows to benefit from all LiveObjects features also for lwm2m devices.

7.2. LwM2M protocol support

In the LwM2M common features, we find the main ones as specified in the OMA 1.0 and 1.1 specifications, here is the supported features as specified in LWM2M specifications.

7.2.1. Supported network stack

Layer Supported protocol

Transport

UDP

Security

DTLS 1.2 (using PSK identity + PSK key)

Session

CoAP (Constrained Application Protocol)

Application

LwM2M 1.0 specifications & LwM2M 1.1 specifications on CoAP

7.2.2. LwM2M 1.0 supported features

Legend

Fully implemented

Not applicable

Not implemented

🚧

On roadmap

Client registration

Feature Live objects implementation

Register

Register update

De-register

Device Management

Feature Live objects implementation

Read

Write

Execute

Create

Delete

Write attributes

🚧

Discover

Information Reporting

Feature Live objects implementation

Observe

Passive cancel observation

Active cancel observation

Notify

Supported format

Feature Live objects implementation

Plain-text

Opaque

Tlv

Json

Resource Model

Feature Live objects implementation

Object

Object instance

Single Resource

Multi-instance Resource

Object Version

Security

Feature Live objects implementation

NoSec

🚧

Pre-Shared-Key

Raw-Public-Key

X.509

Est

Transport binding and mode

Feature Live objects implementation

Udp

Queue Mode

Sms

Access Control

Feature Live objects implementation

Access Control

Attributes

Feature Live objects implementation

Version

Dimension

Minimum Period

Maximum Period

GreateThan

LessThan

Step

7.2.3. LwM2M 1.1 supported features

Legend

Fully implemented

Non applicable

Not implemented

🚧

On roadmap

Device Management

Feature Live objects implementation

Read-Composite

Write-Composite

Registration Live objects implementation

Supported content

format (ct=<format>)

Information Reporting

Feature Live objects implementation

Send

Observe-Composite

Cancel-Observe-Composite

Resource Instance Operation

Registration Live objects implementation

Read

Write

Observe

Cancel observe

Write attributes

Supported additional formats

Resource instance codec tlv txt json opaque cbor senml-json senml-cbor

encoding

decoding

New data type tlv txt json cbor senml-json senml-cbor

Unsigned Integer

coreLnk

New Data Formats Live objects implementation

CBOR

senML-JSON

senML-CBOR

Resource Model

New Attributes Live objects implementation

short server id

server URI

enabler version

epmin/epmax

Security

Encryption type Live objects implementation

OSCORE

🚧

Certificate Usage

Transport binding and mode

Protocol stack Live objects implementation

Tcp

LoRa®

CIoT

🚧

7.2.4. Live Objects integration features

Additionally, the Live Objects service provides the LwM2M device management and specific device representation implemented behind the LwM2M device interface (Live objects connector):

Live objects LwM2M integrated features overview

Interactive

  • Live Objects integration features

    1. LwM2M devices are included in the unified inventory API (covering all connectivities : LwM2M, MQTT, SMS, LoRa, external connector). LwM2M connectivity configuration (include multi-connectivity).

    2. Twin capability management service to manage the LwM2M device objects and stores the latest LwM2M device ressource values.

    3. Custom object management to define and register the OMA owners objects.

  • Specific features

    1. Live Objects exposes an API that can managing the operations on a given device and monitoring the results of each operation.

    2. To improve the usage in a disturbed network environment, retrieving a device representation of a resource and keep this representation updated by the server over a period of time is persistent. when this happens, and after a device re-register, the OBSERVE operations are automatically reactivated then persisted by the TWIN service.

    3. In the other hand, RFC 7641 tries to sync the "most recent state" and doesn’t care about a "complete history". But in Live Objects the complete /part history can be retrieved using the DataRule. The user can configure a datarule, when triggering, the rule generate and store the uplink message sended by the device.

    4. In a bad network environment, the retrieval of resource values from a device and their updating by the server over a period of time can be affected. The resources objects are persistent even when there are many disconnections or packet loss due bad network QOS. When this happens, and after a device re-register, Live Objects automatically reactivate the OBSERVE operations which are then persisted by the TWIN service.

  • Common features used in the Live Objects environment

    1. LwM2M datamessage stream management (Uplink).

    2. LwM2M datamessage decoding.

    3. Firmware update.

    4. Telemetry data sampling in time series, enrichment and pushing to multiple platforms using Live Objects Custom Pipelines and Datamessage Routing.

    5. Telemetry data vizualisation widgets using Live Objects Data Store & Search.

    6. Alarms and notifications on LwM2M device behavior and telemetry data.

7.3. Data formats

Live Objects supports all data formats defined in the LwM2M v1.1 specification.

A client supporting LwM2M v1.0 must support TLV as stated in the LwM2M V1.0 specification (chapter 6.4). A client supporting LwM2M v1.1 must support Plain Text, Opaque, CoRE Link and at least one of SenML CBOR or SenML JSON.
If supporting optional data formats a LwM2M client may inform the server by including them in the Register operation.

When sending a Write Request or a Composite Request, Live Objects encodes the payload with a data format selected from those that are mandatory for the client and those that are declared as supported by the client (sent in the Register operation). The following rules apply:

Table 1. Request format (Write and Composite requests)
LwM2M version request on a singular resource* request on multiple resources* composite request

v1.0

Opaque if declared as supported and the resource is of type opaque

TLV otherwise

TLV

N/A

v1.1

Opaque if the resource is of type opaque

Plain Text otherwise

SenML CBOR if declared as supported

SenML JSON otherwise

SenML CBOR if declared as supported

SenML JSON otherwise

The preferred response data format can be specified by Live Objects for Read, Observe, and their composite variants. If not specified, the client uses its own preferred format. The following rules apply:

Table 2. Preferred response format (Read, Observe and Composite requests)
LwM2M version request on a singular resource* request on multiple resources* composite request

v1.0

not specified

not specified

N/A

v1.1

not specified

not specified

SenML CBOR if declared as supported

SenML JSON otherwise

*Request on a singular resource

Request targeting a single Resource (ex: /3442/0/110) or a multiple Resource Instance (ex: /3442/0/1110/0).

*Request on multiple resources

Request targeting either an Object Instance (ex: /3442/0) or a multiple Resource (ex: /3442/0/1110).

7.4. LwM2M endpoints

7.4.1. CoAP server URI

For the LwM2M protocol, only secured CoAP binding is supported using DTLS Pre-Shared Key (PSK). The command bellow will bind the Live objects LwM2M server to the server CoAP interface. It known as Live objects LwM2M server URI.

    coaps://lwm2m.liveobjects.orange-business.com:5684

7.4.2. Device identifier : Endpoint Name

Known as endpoint client name in OMA specifications. It should be provided to the LwM2M Server during Registration, also should be provided to LwM2M Bootstrap-Server when executing the Bootstrap procedure when is available. This identifier must respect the URN format.

7.4.3. Bootstrap server URI

For the LwM2M protocol, only secured CoAP binding is supported using DTLS Pre-Shared Key (PSK). The command bellow will bind the Live objects LwM2M bootstrap server to the server CoAP interface. It known as Live objects Bootstrap LwM2M server URI.

    coaps://bootstrap.lwm2m.liveobjects.orange-business.com:5684

7.5. Secure your LwM2M connection

7.5.1. Security and encryption

To securing CoAP and due to using UDP with datagram packets without connexion, we optimize the computing effort on the device side (power low consumption), the CoAP transport layer uses the DTLS with a Pre-Shared Key (PSK) to secure the communications between Live Objects and the device fleets. This includes the paired "PSK identity" and shared secret to be used with the Live Objects platform.

DTLS 1.2 is used, to provision and configure your device, you need:

  1. EndPointName

  2. PSK Identity

  3. PSK key (secret)

To learn more, see this section.

As specified in the CoAP rfc7252 specifications, devices should support the Server Name Indication (SNI) to indicate their authority in the SNI HostName field as defined in section 3 of RFC6066. This is needed so that when a host that acts as a virtual server for multiple authorities receives a new DTLS connection, it knows which keys to use for initialise the DTLS session.

7.5.2. DTLS Ciphers suite

During a device register steps, a DTLS session (1.2) use a PSK (Pre-Shared Key) mode. In this case, the device need a mandatory-to-implement cipher suites as specified in the CoAP rfc7252 specifications.

Supported ciphers are (static list) :

Cipher Hex value ID

ECDHE_ECDSA_WITH_AES_128_CCM

0xC0AC

ECDHE_ECDSA_WITH_AES_128_CCM_8

0xC0AE

ECDHE_ECDSA_WITH_AES_128_GCM_SHA256

0xC02B

ECDHE_ECDSA_WITH_AES_256_CCM

0xC0AD

ECDHE_ECDSA_WITH_AES_256_CCM_8

0xC0AF

ECDHE_ECDSA_WITH_AES_256_GCM_SHA384

0xC02C

ECDHE_RSA_WITH_AES_128_GCM_SHA256

0xC02F

ECDHE_RSA_WITH_AES_256_GCM_SHA384

0xC030

ECDHE_PSK_WITH_AES_128_CCM_8_SHA256

0xD003

ECDHE_PSK_WITH_AES_128_CCM_SHA256

0xD005

ECDHE_PSK_WITH_AES_128_GCM_SHA256

0xD001

ECDHE_PSK_WITH_AES_256_GCM_SHA384

0xD002

PSK_WITH_AES_128_CCM

0xC0A4

PSK_WITH_AES_128_CCM_8

0xC0A8

PSK_WITH_AES_128_GCM_SHA256

0x00A8

PSK_WITH_AES_256_CCM

0xC0A5

PSK_WITH_AES_256_CCM_8

0xC0A9

PSK_WITH_AES_256_GCM_SHA384

0x00A9

7.6. LwM2M device register simulation

Once the identity provisioned, the device can perform a register on the server, which mean that the device is ready to receive a LwM2M messages (CoAP). During this request, the device presents its supported object definitions.

The following sample will provide a simulator in Java:

java -jar leshan-client-demo.jar -u lwm2m.liveobjects.orange-business.com:5684 -n <endpoint LWM2M> -i <PSK_identity> -p <PSK_KEY>
Where : -n <endpoint LWM2M>, -i <PSK_identity>, -p <PSK_KEY> hex format.
  • You should see the DeviceTwin in the Parc menu (select LwM2M device twin tab) of your portal.

  • You should be able to apply the operations ( read,write,execute) on a device and see the results in the Parc menu (select LwM2M operation tab) of your portal.

  • If your device can reports value changes while sending data, under certain conditions, you can see the generated data messages in the data menu (select Data messages tab) of your portal.

  • If your device can’t perform a DNS resolution on lwm2m.liveobjects.orange-business.com, set the IP adress of the endpoint in your device connection config.

  • The lwm2m.liveobjects.orange-business.com endpoint can be change, make sure that you can update it on your device parc if necessary.

7.7. LwM2M bootstrap

7.7.1. Principle

The Bootstrap is used to provision essential information (like LwM2M server URIs, credentials to authenticate to the LwM2M servers, etc.) into the LwM2M Client to enable it to register with one or more LwM2M Servers. This Bootstrap information is retrieved from the LwM2M Bootstrap Server.

For more information, please refer to the LwM2M specification.


bootstrap
Figure 1. Overview of LwM2M Bootstrap


7.7.1.1. Bootstrap Configuration

A Bootstrap Configuration defines the bootstrap strategy for a set of Bootstrap Entry:

  • RunServers

  • Run’s key management policy

Example of a Bootstrap Config:

{
    "id": "637d00aedca4b9489573de68",
    "name": "BootstrapConfig",
    "description": "This is a bootstrap config",
    "runServers": [
        {
            "id": "myServer",
            "useLiveObjects": false,
            "lwm2mDefinition": {
                "security": {
                    "shortServerId": 1,
                    "lwm2mServerUri": "coaps://myserver:5684",
                    "securityMode": 1
                },
                "server": {
                    "shortServerId": 1,
                    "lifetime": 200,
                    "binding": "S"
                }
            }
        }
    ],
    "created": "2022-11-22T17:02:38.944Z",
    "updated": "2022-11-22T17:02:38.944Z"
}
Field Description

id

(mandatory) Generated Bootstrap configuration unique identifier. Is used to link the configuration to a Bootstrap Entry.

name

(mandatory) User-defined name for the bootstrap config, must not be empty.

description

(optional) User-defined description for the bootstrap config.

runServers

(mandatory) The run servers configuration.

runServers.id

(mandatory) Run server unique identifier. Will be used also in Bootstrap Entry

runServers.useLiveObjects

(optional) If true, the LiveObjects LwM2M URI will be used as lwm2mServerUr and PSK as the securityMode. If false, they have to be defined. (default: false)

runServers.renewSecurityOnBootstrap

(optional) If true, new credentials (e.g. the PSK identity and secret) will be generated at each Bootstrap. Can be set only if useLiveObjects is true. (default: false)

runServers.lwm2mDefinition

(mandatory) The LwM2M configuration.

runServers.lwm2mDefinition.security

(mandatory) The configuration for the LwM2M Security object (ObjectID=0).

runServers.lwm2mDefinition.security.settings

(optional) Settings for this Security Object (for example, on which instance to write it).

runServers.lwm2mDefinition.security.settings.objectInstanceId

(optional) The instance ID that will be used for this Object. If not specified, the ID is automatically assigned incrementally from 0 for the first Run Server in the list. The Security Object instance used for the Bootstrap Server is avoided (a Discover operation is performed to identify the ID used).

runServers.lwm2mDefinition.security.lwm2mServerUri

(mandatory if useLiveObjects is false) Uniquely identifies the LwM2M Server or LwM2M Bootstrap-Server. Present if and only if useLiveObjects is false.

runServers.lwm2mDefinition.security.securityMode

(mandatory if useLiveObjects is false) Determines what credentials are being used by the LwM2M Client and the LwM2M Server. Present if and only if useLiveObjects is false. Allowed values :

- 0: PSK.

- 1: RPK.

- 2: CERTIFICATE.

- 3: NO_SEC.

- 4: CERTIFICATE_WITH_EST.

runServers.lwm2mDefinition.security.serverPublicKey

(optional) Stores the LwM2M Server’s, respectively LwM2M Bootstrap-Server’s, certificate, public key (RPK mode) or trust anchor. The Certificate Mode Resource determines the content of this resource. Present if and only if useLiveObjects is false.

runServers.lwm2mDefinition.security.smsSecurityMode

(optional) Determines which SMS security mode is used:

- 0: Reserved for future use

- 1: DTLS mode (Device terminated) PSK mode assumed

- 2: Secure Packet Structure mode (Smartcard terminated)

- 3: NoSec mode

- 4: Reserved mode (DTLS mode with multiplexing Security Association support)

- 5-203: Reserved for future use

- 204-255: Proprietary modes

runServers.lwm2mDefinition.security.lwm2mServerSmsNumber

(optional) MSISDN used by the LwM2M Client to send messages to the LwM2M Server via the SMS binding.

runServers.lwm2mDefinition.security.shortServerId

(mandatory) This identifier uniquely identifies each LwM2M Server configured for the LwM2M Client.

runServers.lwm2mDefinition.security.clientHoldOffTime

(optional) The number of seconds to wait before initiating a Client Initiated Bootstrap once the LwM2M Client has determined it should initiate this bootstrap mode.

runServers.lwm2mDefinition.security.bootstrapServerAccountTimeout

(optional) The LwM2M Client MUST purge the LwM2M Bootstrap-Server Account after the timeout value given by this resource.

runServers.lwm2mDefinition.security.matchingType

(optional) The Matching Type Resource specifies how the certificate or raw public key in the Server Public Key is presented. Four values are currently defined:

- 0: Exact match. This is the default value and also corresponds to the functionality of LwM2M v1.0. Hence, if this resource is not present then the content of the Server Public Key Resource corresponds to this value.

- 1: SHA-256 hash [RFC6234]

- 2: SHA-384 hash [RFC6234]

- 3: SHA-512 hash [RFC6234]

runServers.lwm2mDefinition.security.sni

(optional) This resource holds the value of the Server Name Indication (SNI) value to be used during the TLS handshake. When this resource is present then the LwM2M Server URI acts as the address of the service while the SNI value is used for matching a presented certificate, or PSK identity.

runServers.lwm2mDefinition.security.certificateUsage

(optional) The Certificate Usage Resource specifies the semantic of the certificate or raw public key stored in the Server Public Key Resource, which is used to match the certificate presented in the TLS/DTLS handshake. The currently defined values are 0 for "CA constraint", 1 for "service certificate constraint", 2 for "trust anchor assertion", and 3 for "domain-issued certificate". When this resource is absent, value (3) for domain issued certificate mode is assumed. More details about the semantic of each value can be found in the security consideration section of the LwM2M specification. Present if and only if useLiveObjects is false.

runServers.lwm2mDefinition.security.dtlsTlsCiphersuite

(optional) When this resource is present it instructs the TLS/DTLS client to propose the indicated ciphersuite(s) in the ClientHello of the handshake. A ciphersuite is indicated as a 32-bit integer value. The IANA TLS ciphersuite registry is maintained at www.iana.org/assignments/tls-parameters/tls-parameters.xhtml. As an example, the TLS_PSK_WITH_AES_128_CCM_8 ciphersuite is represented with the following string "0xC0,0xA8". To form an integer value the two values are concatenated. In this example, the value is 0xc0a8 or 49320.

runServers.lwm2mDefinition.server

(mandatory) The configuration for the LwM2M Server object (ObjectID=1).

runServers.lwm2mDefinition.server.settings

(optional) Settings for this Server Object (for example, on which instance to write it).

runServers.lwm2mDefinition.server.settings.objectInstanceId

(optional) The instance ID that will be used for this Object. If not specified, the ID is automatically assigned incrementally from 0 for the first Run Server in the list.

runServers.lwm2mDefinition.server.shortServerId

(mandatory) Used as link to associate server Object Instance.

runServers.lwm2mDefinition.server.lifetime

(optional) Specify the lifetime of the registration in seconds.

runServers.lwm2mDefinition.server.defaultMinimumPeriod

(optional) The default value the LwM2M Client should use for the Minimum Period of an Observation

runServers.lwm2mDefinition.server.defaultMaximumPeriod

(optional) The default value the LwM2M Client should use for the Maximum Period of an Observation

runServers.lwm2mDefinition.server.disableTimeout

(optional) A period to disable the Server. After this period, the LwM2M Client MUST perform registration process to the Server.

runServers.lwm2mDefinition.server.notificationStoringWhenDisabledOrOffline

(optional) If true, the LwM2M Client stores “Notify” operations to the LwM2M Server while the LwM2M Server account is disabled or the LwM2M Client is offline

runServers.lwm2mDefinition.server.binding

(optional) Defines the transport binding configured for the LwM2M Client. It is a list composed of the following elements:

- U: UDP.

- T: TCP.

- S: SMS.

- N: NON_IP.

- Q: Queue Mode (removed since LwM2M 1.1). Note: the bindings UQ, SQ and UQS are allowed, UQSQ and USQ are not.

runServers.lwm2mDefinition.server.apnLink

(optional) If this resource is defined, it provides a link to the APN connection profile Object Instance (OMNA registered Object ID:11) to be used to communicate with this server. The instance id must be provided.

runServers.lwm2mDefinition.server.registrationPriorityOrder

(optional) The LwM2M Client sequences the LwM2M Server registrations in increasing order of this value. If this value is not defined, registration attempts to this server are not impacted by other server registrations.

runServers.lwm2mDefinition.server.initialRegistrationDelayTimer

(optional) The delay before registration is attempted for this LwM2M Server based upon the completion of registration of the previous LwM2M Server in the registration order. This is only applied until the first successful registration after a successful bootstrapping sequence.

runServers.lwm2mDefinition.server.registrationFailureBlock

(optional) When set to true and registration to this LwM2M server fails, the LwM2M Client blocks registration to other servers in the order. When set to false, the LwM2M Client proceeds with registration to the next server in the order.

runServers.lwm2mDefinition.server.bootstrapOnRegistrationFailure

(optional) If set to true, this indicates that the LwM2M Client should re-bootstrap when either registration is explicitly rejected by the LwM2M Server or registration is considered as failing as dictated by the other resource settings. If set to false, the LwM2M Client will continue with the registration attempts as dictated by the other resource settings.

runServers.lwm2mDefinition.server.communicationRetryCount

(optional) The number of successive communication attempts before which a communication sequence is considered as failed.

runServers.lwm2mDefinition.server.communicationRetryTimer

(optional) The delay between successive communication attempts in a communication sequence. This value is multiplied by two to the power of the communication retry attempt minus one (2**(retry attempt-1)) to create an exponential back-off.

runServers.lwm2mDefinition.server.communicationSequenceDelayTimer

(optional) The delay between successive communication sequences. A communication sequence is defined as the exhaustion of the Communication Retry Count and Communication Retry Timer values. A communication sequence can be applied to server registrations or bootstrapping attempts. MAX_VALUE means do not perform another communication sequence.

runServers.lwm2mDefinition.server.communicationSequenceRetryCount

(optional) The number of successive communication sequences before which a registration attempt is considered as failed.

runServers.lwm2mDefinition.server.trigger

(optional) Using the Trigger Resource a LwM2M Client can indicate whether it is reachable over SMS (value set to 'true') or not (value set to 'false')

runServers.lwm2mDefinition.server.preferredTransport

(optional) Only a single transport binding SHALL be present. When the LwM2M client supports multiple transports, it MAY use this transport to initiate a connection. This resource can also be used to switch between multiple transports e.g. a non-IP device can switch to UDP transport to perform firmware updates.

runServers.lwm2mDefinition.server.muteSend

(optional) If true or the Resource is not present, the LwM2M Client Send command capability is de-activated. If false, the LwM2M Client Send Command capability is activated.

Note : runServers.lwm2mDefinition.security.shortServerId and runServers.lwm2mDefinition.server.shortServerId must be equal.

7.7.1.2. Bootstrap Entry

A Bootstrap Entry is link to a Bootstrap Config and contains:

  • the credentials used to authenticate to the LwM2M Bootstrap server

  • the parameters of the Bootstrap Config specific to an endpoint, namely the credentials used to authenticate to the LwM2M Run server

  • information about past Bootstrap sessions

Example of a Bootstrap Entry:

{
    "endpointName": "my_endpoint",
    "security": {
        "mode": "PSK",
        "pskInfo": {
            "identity": "my_endpoint",
            "secret": "0123456789ABCDEF0123456789ABCDEF"
        }
    },
    "definition": {
        "bootstrapConfigId": "637d00cfdca4b9489573de69",
        "runServers": [
            {
                "id": "LOServer",
                "security": {
                    "pskInfo": {
                        "identity": "my_endpoint",
                        "secret": "0123456789ABCDEF0123456789ABCDEF"
                    }
                }
            }
        ]
    },
    "activity": {
        "status": "FINISHED",
        "endpointBootstrapConfig": {
            "runServers": [
                {
                    "security": {
                        "shortServerId": 1,
                        "lwm2mServerUri": "coaps://lwm2m.liveobjects.orange-business.com:5684",
                        "securityMode": 0,
                        "publicKeyOrIdentity": "urn:imei:000000000000000",
                        "secretKey": "***",
                        "clientHoldOffTime": 0,
                        "bootstrapServerAccountTimeout": 0
                    },
                    "server": {
                        "shortServerId": 1,
                        "lifetime": 3600,
                        "defaultMinimumPeriod": 0,
                        "defaultMaximumPeriod": 500,
                        "disableTimeout": 0,
                        "notificationStoringWhenDisabledOrOffline": true,
                        "binding": "U"
                    }
                }
            ]
        },
        "bootstrapRequestCount": 6,
        "lastBootstrapRequestDate": "2023-01-13T11:50:28.086Z",
        "bootstrapFinishCount": 4,
        "lastBootstrapFinishDate": "2023-01-13T11:50:36.221Z"
    },
    "created": "2023-01-11T17:53:57.021Z",
    "updated": "2023-01-13T11:50:36.227Z"
}
Field Description

endpointName

(mandatory) The endpoint client name.

security

(mandatory) The security information to authenticate to the LwM2M Bootstrap server.

security.mode

(mandatory) The security mode used to authenticate to the LwM2M Bootstrap server.

security.pskInfo

(mandatory) The Pre-Shared Key (PSK) information to authenticate to the LwM2M Bootstrap server.

security.pskInfo.identity

(mandatory) The "bootstrap" PSK Identity.

security.pskInfo.secret

(mandatory) The "bootstrap" PSK secret key.

definition

(optional) The Bootstrap Config parameters for the endpoint (must be defined for the Bootstrap to work).

definition.bootstrapConfigId

(optional) The identifier of the Bootstrap Config to use for the endpoint (must be defined for the Bootstrap to work).

definition.runServers

(optional) The parameters for the runServers defined in Bootstrap Config (depending on the Bootstrap config it can be required for the Bootstrap to work).

definition.runServers.id

(mandatory) The identifier of the runServer defined in Bootstrap Config.

definition.runServers.security

(optional) The security information to authenticate to the LwM2M Run server (depending on the Bootstrap config it can be required for the Bootstrap to work).

definition.runServers.security.pskInfo

(mandatory) The Pre-Shared Key (PSK) information to authenticate to this LwM2M Run server.

definition.runServers.security.pskInfo.identity

(optional) The "run" PSK Identity. If it is not defined, the Identity of the PSK used to authenticate to the LwM2M Bootstrap server is used.

definition.runServers.security.pskInfo.secret

(mandatory) The "run" PSK secret key.

activity

(read only) Information about past Bootstrap session.

activity.status

(read only) status regarding the Bootstrap

activity.endpointBootstrapConfig

(read only) The last Bootstrap configuration that was sent to the LwM2M client. Refer to the Bootstrap Config for the description of each parameter except for publicKeyOrIdentity and secretKey described below.

activity.endpointBootstrapConfig.publicKeyOrIdentity

(read only) The LwM2M Client’s certificate, public key (RPK mode) or PSK Identity (PSK mode).

activity.endpointBootstrapConfig.secretKey

(read only) The secret key (PSK mode) or private key (RPK or certificate mode).

activity.bootstrapRequestCount

(read only) The number of times a Bootstrap sequence has been initiated (a Bootstrap-Request has been received by the LwM2M server).

activity.lastBootstrapRequestDate

(read only) The last time a Bootstrap sequence was initiated (a Bootstrap-Request has been received by the LwM2M server).

activity.bootstrapFinishCount

(read only) The number of times a Bootstrap sequence has been successfully completed (a Bootstrap-Finish has been sent by the LwM2M server).

activity.lastBootstrapFinishDate

(read only) The last time a Bootstrap sequence has been successfully completed (a Bootstrap-Finish has been sent by the LwM2M server).

created

(read only) Date on which the Bootstrap Entry was created.

updated

(read only) Date on which the Bootstrap Entry was last updated.

7.7.1.3. Bootstrap Sequence
7.7.1.3.1. General case

Before being able to bootstrap a device, it is needed to provision a Bootstrap Entry for the device and link it to a Bootstrap Config.
The Bootstrap sequence starts with the device sending a Bootstrap-Request (preceded by a DTLS Handshake). If the instance IDs to use for the Security Objects are not defined in the Bootstrap Config, a Bootstrap-Discover is sent by LiveObjects to be able to know which Security Object instance holds the Bootstrap server information and avoid it. The Security, Server and OSCORE Objects are deleted. The Security and Server Objects are then written using the parameters defined in the Bootstrap Config and the credentials defined in the Bootstrap Entry.
The Bootstrap sequence ends with LiveObjects sending a Bootstrap-Finish. The device can then register to the LwM2M Run servers.


Bootstrap sequence
Figure 2. Bootstrap sequence diagram


The Bootstrap status is visible in the Bootstrap Entry. The status evolves as follows during the Bootstrap sequence:


Bootstrap sequence
Figure 3. Bootstrap state machine


7.7.1.3.2. Using LiveObjects as Run Server

To use LiveObjects as Run Server, the Bootstrap Config must be created with the parameter useLiveObjects set to true. Refer to this Bootstrap Config creation example. A device must be created (with the same endpoint name as the Bootstrap Entry). The device can be declared as being managed by the LiveObjects Bootstrap Server (bootstrap.managed = true and w/o security info) or not (bootstrap.managed = false and w/ security info). Refer to: LwM2M Device or LwM2M Device managed by Bootstrap creation examples. If the device is created with bootstrap.managed = true (and in the same tenant as the Entry), the security info will be automatically provisioned in the LiveObjects device representation upon bootstrapping. Otherwise, they must be provisioned manually during the device creation, and they will be checked during bootstrap (i.e. do they match the security info that were provisioned in the Bootstrap Entry and that will be set on the physical device). If an error occurs during the automatic provisioning of the security info or if there is a security info mismatch, the Bootstrap sequence will fail. After a successful Bootstrap sequence, the device will register with the LiveObjects LwM2M Run server.


Bootstrap sequence
Figure 4. Bootstrap sequence using LiveObjects as Run Server


7.7.1.3.3. With credentials generated at Bootstrap time

The following diagram describes the sequence when the run credentials are generated at Bootstrap time.
The Bootstrap Config has to be created with the renewSecurityOnBootstrap parameter set to true. Refer to this Bootstrap Config creation example. The Bootstrap Entry should be created without Run credentials (otherwise they will be just be ignored).
A device must be created on LiveObjects with the bootstrap.managed parameter set to true (and with the same endpoint name and on the same account as the Bootstrap Entry). Refer to this Device creation example.
At each Bootstrap new credentials will be generated and automatically provisioned in the LiveObjects device representation. If an error occurs during the credentials provisioning, the Bootstrap sequence will fail. After a successful Bootstrap sequence, the device will register with the LiveObjects LwM2M Run server using the generated credentials.


Bootstrap sequence
Figure 5. Bootstrap sequence with credentials generated at bootstrap time


7.7.2. Bootstrap Configurations API

This section includes API call examples for the Bootstrap Configs management.

You can refer to the swagger documentation to list all available APIs.

7.7.2.1. Create a bootstrap config

Example:

POST /api/v1/bootstrap/lwm2m/configs
{
    "name" : "BootstrapConfig",
    "description" : "This is a bootstrap config",
    "runServers" : [
        {
            "id" : "myServer",
            "useLiveObjects" : false,
            "lwm2mDefinition" : {
                "security" : {
                    "shortServerId" : 1,
                    "lwm2mServerUri" : "coaps://myserver:5684",
                    "securityMode" : 1
                },
                "server" : {
                    "shortServerId" : 1,
                    "lifetime" : 200,
                    "binding" : "S"
                }
            }
        }
    ]
}

Response

201 CREATED
{
    "id": "637d00aedca4b9489573de68",
    "name": "BootstrapConfig",
    "description": "This is a bootstrap config",
    "runServers": [
        {
            "id": "myServer",
            "useLiveObjects": false,
            "lwm2mDefinition": {
                "security": {
                    "shortServerId": 1,
                    "lwm2mServerUri": "coaps://myserver:5684",
                    "securityMode": 1
                },
                "server": {
                    "shortServerId": 1,
                    "lifetime": 200,
                    "binding": "S"
                }
            }
        }
    ],
    "created": "2022-11-22T17:02:38.944Z",
    "updated": "2022-11-22T17:02:38.944Z"
}
7.7.2.2. Create a LiveObjects bootstrap config

This example will produce a bootstrap config with the LiveObjects LwM2M uri as lwm2mServerUri and PSK as the securityMode.

Example:

POST /api/v1/bootstrap/lwm2m/configs
{
    "name": "LOBootstrapConfig",
    "description": "This is a LO bootstrap config",
    "runServers": [
        {
            "id": "LOServer",
            "useLiveObjects": true,
            "renewSecurityOnBootstrap": false,
            "lwm2mDefinition": {
                "security": {
                    "shortServerId": 1
                },
                "server": {
                    "shortServerId": 1,
                    "lifetime": 300,
                    "binding": "U"
                }
            }
        }
    ]
}

Response

201 CREATED
{
    "id": "637d00cfdca4b9489573de69",
    "name": "LOBootstrapConfig",
    "description": "This is a LO bootstrap config",
    "runServers": [
        {
            "id": "LOServer",
            "useLiveObjects": true,
            "renewSecurityOnBootstrap": false,
            "lwm2mDefinition": {
                "security": {
                    "shortServerId": 1
                },
                "server": {
                    "shortServerId": 1,
                    "lifetime": 300,
                    "binding": "U"
                }
            }
        }
    ],
    "created": "2022-11-22T17:03:11.197Z",
    "updated": "2022-11-22T17:03:11.197Z"
}
7.7.2.3. Create a LiveObjects bootstrap config with credentials generation

This example will produce a bootstrap config with the LiveObjects LwM2M uri as lwm2mServerUri and PSK as the securityMode.

A new run Pre-Shared Key will be generated (both the id and the secret) at each Bootstrap.

Example:

POST /api/v1/bootstrap/lwm2m/configs
{
    "name": "LOBootstrapConfig",
    "description": "This is a LO bootstrap config",
    "runServers": [
        {
            "id": "LOServer",
            "useLiveObjects": true,
            "renewSecurityOnBootstrap": true,
            "lwm2mDefinition": {
                "security": {
                    "shortServerId": 1
                },
                "server": {
                    "shortServerId": 1,
                    "lifetime": 300,
                    "binding": "U"
                }
            }
        }
    ]
}

Response

201 CREATED
{
    "id": "637d00cfdca4b9489573de69",
    "name": "LOBootstrapConfig",
    "description": "This is a LO bootstrap config",
    "runServers": [
        {
            "id": "LOServer",
            "useLiveObjects": true,
            "renewSecurityOnBootstrap": true,
            "lwm2mDefinition": {
                "security": {
                    "shortServerId": 1
                },
                "server": {
                    "shortServerId": 1,
                    "lifetime": 300,
                    "binding": "U"
                }
            }
        }
    ],
    "created": "2022-11-22T17:03:11.197Z",
    "updated": "2022-11-22T17:03:11.197Z"
}

7.7.3. Bootstrap Entries API

This section includes API call examples for the Bootstrap Entries management.

You can refer to the swagger documentation to list all available APIs.

7.7.3.1. Create a bootstrap entry

Example:

POST /api/v1/bootstrap/lwm2m/entries
{
    "endpointName": "my_endpoint",
    "security": {
        "mode": "PSK",
        "pskInfo": {
            "identity": "my_endpoint",
            "secret": "0123456789ABCDEF0123456789ABCDEF"
        }
    },
    "definition": {
        "bootstrapConfigId": "63b6dd0d4a3f024c43b88c31",
        "runServers": [
            {
                "id": "LOServer",
                "security": {
                    "pskInfo": {
                        "identity": "my_endpoint",
                        "secret": "0123456789ABCDEF0123456789ABCDEF"
                    }
                }
            }
        ]
    }
}

Response

201 CREATED
{
    "endpointName": "my_endpoint",
    "security": {
        "mode": "PSK",
        "pskInfo": {
            "identity": "my_endpoint"
        }
    },
    "definition": {
        "bootstrapConfigId": "63b6dd0d4a3f024c43b88c31",
        "runServers": [
            {
                "id": "LOServer",
                "security": {
                    "pskInfo": {
                        "identity": "my_endpoint",
                        "secret": "***"
                    }
                }
            }
        ]
    },
    "activity": {
        "status": "NEVER_REQUESTED",
        "bootstrapRequestCount": 0,
        "bootstrapFinishCount": 0
    },
    "created": "2023-01-10T16:57:38.299Z",
    "updated": "2023-01-10T16:57:38.299Z"
}
7.7.3.2. Update the bootstrapConfigId in a bootstrap entry

Example:

PUT /api/v1/bootstrap/lwm2m/entries/my_endpoint/definition/bootstrapConfigId
"6374fc20c63f896edc10726d"

Response

200 OK
{
    "endpointName": "my_endpoint",
    "security": {
        "mode": "PSK",
        "pskInfo": {
            "identity": "my_endpoint"
        }
    },
    "definition": {
        "bootstrapConfigId": "6374fc20c63f896edc10726d",
        "runServers": [
            {
                "id": "LOServer",
                "security": {
                    "pskInfo": {
                        "identity": "my_endpoint",
                        "secret": "***"
                    }
                }
            }
        ]
    },
    "activity": {
        "status": "NEVER_REQUESTED",
        "bootstrapRequestCount": 0,
        "bootstrapFinishCount": 0
    },
    "created": "2023-01-10T16:57:38.299Z",
    "updated": "2023-01-10T18:03:05.488Z"
}
7.7.3.3. Get a bootstrap entry

Example:

GET /api/v1/bootstrap/lwm2m/entries/my_endpoint?showSecuritySecrets=true

Response

200 OK
{
    "endpointName": "my_endpoint",
    "security": {
        "mode": "PSK",
        "pskInfo": {
            "identity": "my_endpoint"
        }
    },
    "definition": {
        "bootstrapConfigId": "6374fc20c63f896edc10726d",
        "runServers": [
            {
                "id": "LOServer",
                "security": {
                    "pskInfo": {
                        "secret": "0123456789ABCDEF0123456789ABCDEF"
                    }
                }
            }
        ]
    },
    "activity": {
        "status": "FINISHED",
        "endpointBootstrapConfig": {
            "runServers": [
                {
                    "security": {
                        "shortServerId": 1,
                        "lwm2mServerUri": "coaps://lwm2m.liveobjects.orange-business.com:5684",
                        "securityMode": 0,
                        "publicKeyOrIdentity": "my_endpoint",
                        "secretKey": "0123456789ABCDEF0123456789ABCDEF",
                        "clientHoldOffTime": 0,
                        "bootstrapServerAccountTimeout": 0
                    },
                    "server": {
                        "shortServerId": 1,
                        "lifetime": 3600,
                        "defaultMinimumPeriod": 0,
                        "defaultMaximumPeriod": 500,
                        "disableTimeout": 0,
                        "notificationStoringWhenDisabledOrOffline": true,
                        "binding": "U"
                    }
                }
            ]
        },
        "bootstrapRequestCount": 1,
        "lastBootstrapRequestDate": "2023-01-10T18:05:23.693Z",
        "bootstrapFinishCount": 1,
        "lastBootstrapFinishDate": "2023-01-10T18:05:31.907Z"
    },
    "created": "2023-01-10T16:57:38.299Z",
    "updated": "2023-01-10T18:03:05.488Z"
}
7.7.3.4. List bootstrap entries

Example:

GET /api/v1/bootstrap/lwm2m/entries?limit=10&bookmarkEndpointName=my_endpoint

Response

200 OK
[
    {
        "endpointName": "urn:imei:000000000000000",
        "security": {
            "mode": "PSK",
            "pskInfo": {
                "identity": "urn:imei:000000000000000"
            }
        },
        "definition": {
            "bootstrapConfigId": "63bbf9244bdab8538b9adcae",
            "runServers": [
                {
                    "id": "LOServer",
                    "security": {
                        "pskInfo": {
                            "secret": "***"
                        }
                    }
                }
            ]
        },
        "activity": {
            "status": "FINISHED",
            "endpointBootstrapConfig": {
                "runServers": [
                    {
                        "security": {
                            "shortServerId": 1,
                            "lwm2mServerUri": "coaps://lwm2m.liveobjects.orange-business.com:5684",
                            "securityMode": 0,
                            "publicKeyOrIdentity": "urn:imei:000000000000000",
                            "secretKey": "***",
                            "clientHoldOffTime": 0,
                            "bootstrapServerAccountTimeout": 0
                        },
                        "server": {
                            "shortServerId": 1,
                            "lifetime": 3600,
                            "defaultMinimumPeriod": 0,
                            "defaultMaximumPeriod": 500,
                            "disableTimeout": 0,
                            "notificationStoringWhenDisabledOrOffline": true,
                            "binding": "U"
                        }
                    }
                ]
            },
            "bootstrapRequestCount": 6,
            "lastBootstrapRequestDate": "2023-01-13T11:50:28.086Z",
            "bootstrapFinishCount": 4,
            "lastBootstrapFinishDate": "2023-01-13T11:50:36.221Z"
        },
        "created": "2023-01-11T17:53:57.021Z",
        "updated": "2023-01-13T11:50:36.227Z"
    },
    {
        "endpointName": "urn:imei:000000000000001",
        "security": {
            "mode": "PSK",
            "pskInfo": {
                "identity": "urn:imei:000000000000001"
            }
        },
        "definition": {
            "bootstrapConfigId": "63bbf9244bdab8538b9adcae",
            "runServers": [
                {
                    "id": "LOServer",
                    "security": {
                        "pskInfo": {
                            "secret": "***"
                        }
                    }
                }
            ]
        },
        "activity": {
            "status": "FINISHED",
            "endpointBootstrapConfig": {
                "runServers": [
                    {
                        "security": {
                            "shortServerId": 1,
                            "lwm2mServerUri": "coaps://lwm2m.liveobjects.orange-business.com:5684",
                            "securityMode": 0,
                            "publicKeyOrIdentity": "urn:imei:000000000000001",
                            "secretKey": "***",
                            "clientHoldOffTime": 0,
                            "bootstrapServerAccountTimeout": 0
                        },
                        "server": {
                            "shortServerId": 1,
                            "lifetime": 3600,
                            "defaultMinimumPeriod": 0,
                            "defaultMaximumPeriod": 500,
                            "disableTimeout": 0,
                            "notificationStoringWhenDisabledOrOffline": true,
                            "binding": "U"
                        }
                    }
                ]
            },
            "bootstrapRequestCount": 13,
            "lastBootstrapRequestDate": "2023-01-13T12:30:00.594Z",
            "bootstrapFinishCount": 4,
            "lastBootstrapFinishDate": "2023-01-13T12:30:00.912Z"
        },
        "created": "2023-01-13T10:22:41.821Z",
        "updated": "2023-01-13T12:30:00.921Z"
    }
]

7.7.4. Bootstrap entries mass import tutorial

The mass import will be fully available soon on the Live Objects portal, but you can already use our API to import batches of bootstrap entries into Live Objects from a .csv file with the help of Postman, a popular and free API toolbox. Simply follow the step by step tutorial below, you do not need any development skills for this.

7.7.4.1. How to import a list of bootstrap entries from a (CSV file)
7.7.4.1.1. Requirements
  1. Install Postman on your desktop : You can download it from this link download Postman

  2. Create an Api key with "customized" profil + DEVICE_R and DEVICE_W roles : here is the API key configuration requirements, and here is how to create an API key if you don’t have it.

  3. set your Api Key value in the key tab.

Interactive

  1. If you don’t have a bootstrap configuration, create a new one, and save the id.

7.7.4.1.2. Build a list of entries under CSV format file
field endpointName pskInfo.identity pskInfo.secret bootstrapConfigId runServers.id runServers.security.pskInfo.identity runServers.security.pskInfo.secret

entry1

my_endpointName1

pskIdentity1

secret1

bootstrap_configId

runServers.id

runServers.security.pskInfo.identity1

runServers.security.pskInfo.secret1

entry2

my_endpointName2

pskIdentity2

secret2

bootstrap_configId

runServers.id

runServers.security.pskInfo.identity2

runServers.security.pskInfo.secret2

Here is a CSV template : to be completed by your device entries.
The header column of your CSV should contain the exact field id and it will be instantiated during the script execution in both the script and the endpoint.
7.7.4.1.3. Build and write the postman script
  1. We are using this endpoint to create a postman request:

    POST api/v1/bootstrap/lwm2m/entries/
  2. In postman, put your Api key : in the "Headers" window, add in the KEY cells, the variable x-api-key and set it with the Api key value.

  3. In the "Body" window, set this Json :

    {
        "endpointName": "{{endpointName}}",
        "security": {
            "mode": "PSK",
            "pskInfo": {
                "identity": "{{pskInfo.identity}}",
                "secret": "{{pskInfo.secret}}"
            }
        },
        "definition": {
            "bootstrapConfigId": "{{bootstrapConfigId}}",
            "runServers": [
                {
                    "id": "{{runServers.id}}",
                    "security": {
                        "pskInfo": {
                            "identity": "{{runServers.security.pskInfo.identity}}",
                            "secret": "{{runServers.security.pskInfo.secret}}"
                        }
                    }
                }
            ]
        }
    }

    Interactive

  4. In the "Pre-request Script" cell, report the following script to monitor the operation:

 console.log("body contains endpointName" + "->" + data.endpointName)
 console.log(pm.response.json())

Interactive . The script is ready.

The Json body format and the fields are described here.

7.7.4.2. Script execution
  1. Launch the runner (in postman at the bottom right) Interactive

  2. Select your CSV entries file

  3. Check with preview button : postman must read correctely the data’s (the fields and values must be match). Interactive

  4. Drag and drop your endpoint, in the run order, and select your endpoint for running. Interactive

  5. Set a delay between 2 requests to avoid consuming the API’s live objects quotas limits : reaching limits of API will be causes some troubles → check the limits.

  6. Now the Postman script can be run, queries provision every entry you defined in the CSV file and are now displayed in your portal’s LwM2M bootstrap list.

7.8. LwM2M device Twin

7.8.1. Principle

The DeviceTwin is a Live Objects service that can collect, update and display the device resources information whether the device is connected to Live Objects or not.The device twin is created when the LwM2M device is created in Live Objects.Because the device twin representation is stored by Live Objects, the service can be collect and report device resources and state from apps and other services.

DeviceTwin feature is a way to define, retrieve or interact with a Twin representation of a device.

Interactive

The way to define entities supported and instantiated by a device is called a TwinModel, it’s a list of ObjectsDefinitions where each object includes a list of AttributesDefinitions.

Note: LiveObjects TwinModel is compatible with OMA LWM2M model.

Each twin-capable physical device (LWM2M) connected to LiveObjects has an associated DeviceTwin:

  • a DeviceTwin is a list of supportedObjects, instantiatedObjects, and reportedValues.

  • it is possible to send orders (downlink) to a DeviceTwin using commands representation called TwinOperation.

And when a device reports value changes, LiveObjects could produce an associated data message under certain conditions. This condition are handled by a tenant DataRule entry.

7.8.2. Use cases

DeviceTwin use cases are

From Customer API

From Device to LiveObjects

  • a device uses Coap + LwM2M to talk to LiveObjects,

  • a device reports the supported and instantiated objects,

  • a device reports the attribute values.

  • a device respond to a twin operation. :imagesDir: lo_manual_v2/lwm2m_main/lwm2m_twin/images

7.8.3. Model

LiveObjects Twin Model is a specification of object definitions.

A Twin Model is a tree of objectDefinitions where each objectDefinition includes attributeDefinitions.

Twin Model is compatible with the OMA LWM2M Specifications.

Overview of Twin Model

Interactive

  • an ObjectDefinition can have 0, 1 or more children,

  • a root ObjectDefinition has no parent,

  • there is one root Object definition for LwM2M model (objectDefinitionId=urn:oma:lwm2m)

  • direct children of urn:oma:lwm2m are normalized.

Children ObjectDefinition of urn:oma:lwm2m represents LwM2M Objects, where a Twin Model AttributeDefinition represents a LwM2M Object Resource.

For example the Firmware Update LwM2M Object (Object Id=5) has a Resource called PkgName (Id=6):

Firmware Update LwM2M Object 5

landing

7.8.3.1. Model - ObjectDefinition

Firmware Update Object is represented by the following ObjectDefinition:

Field Value Comment

owner

A public definition has no owner.

objectDefinitionId

urn:oma:lwm2m:5:1.1

Object-definition unique identifier.

For example, objectDefinitionId urn:oma:lwm2m:5:1.1 refers to Object Id 5 in version 1.1 of the oma lwm2m

pathSegment

5

Current segment of the path

name

Firmware Update

Original name

description

…​

Description of the object

minoccurs

0

Minimal occurrence (0 means optional, 1 means mandatory and at least 1 is required)

maxoccurs

1

Maximal occurrence (0 means infinite instances are allowed (unbounded), 1 means maximum 1 instance is allowed

type

OBJECT_MAP

Type of object. possible values are OBJECT, OBJECT_MAP.

- OBJECT means that this is a single object

- OBJECT_MAP means that this object is a map of objects, and that a path of such an object instance is always using a map index.

In LwM2M, every object is of type OBJECT_MAP (except the root node)

operations

[ "READ", "WRITE" ]

Array of possible operations on the object. Possible values are READ, WRITE.

- READ : when applied on an Object, it means a READ operation for all the available Attributes of the Object.

- WRITE when applied on an Object, it means a WRITE operation on all the Attributes of the Object

parent

urn:oma:lwm2m

The objectDefinitionId of the parent object. All LwM2M objects are direct children of urn:oma:lwm2m.

attributes

[…​, {"pathSegment" : "6", "name" : "PkgName", "minoccurs" : 0, "maxoccurs" : 1, "type" : "STRING", "operations" : [ "READ"] } ]

A list of AttributeDefinition. For example, list of Firmware Update attributes.

7.8.3.2. Model - AttributeDefinition

PkgName Resource is represented by the following AttributeDefinition:

Field Value Comment

pathSegment

6

Current segment of the path

name

PkgName

Original name

description

…​

Description of the attribute

minoccurs

0

Minimal occurrence (0 means optional, 1 means mandatory and at least 1 is required)

maxoccurs

1

Maximal occurrence (0 means infinite instances are allowed (unbounded), 1 means maximum 1 instance is allowed

type

STRING

Type of attribute. Supported values are : STRING, INTEGER, UNSIGNED_INTEGER, BOOLEAN, FLOAT, BASE64, DATETIME.

- STRING : represented as UTF-8 string.

- INTEGER : represented as ASCII signed integer 1, 2,4 or 8 bytes

- UNSIGNED_INTEGER : represented as ASCII unsigned integer 1, 2,4 or 8 bytes

- BOOLEAN : represented as ASCII value 0 or 1

- FLOAT : represented as a 32 or 64-bit floating point values

- BASE64 : represented as a sequence of binary octets

- DATETIME : represented as a Unix Time. A signed integer representing the number of seconds since Jan 1st, 1970 in the UTC time zone

operations

[ "READ", "WRITE", "EXECUTE" ]

Array of possible operations on the attribute. Possible values are READ, WRITE, EXECUTE.

- EXECUTE, only on an attribute, it means a EXECUTE operation on the Attribute of the Object

7.8.3.3. Model management

In the Twin Model, we distinguish two types of models:

  • public models that are defined for the entire LiveObjects platform. For LwM2M, the ObjectIDs can range from 0 to 32768.

  • custom models that are defined per LiveObjects account. For LwM2M, the ObjectIDs are restricted to the 10241 - 42800 range.

For a given ID, the custom model takes precedence over the public model if both exist.
For the LwM2M protocol, models with IDs between 10241 and 32768 are published by the OMA, so care should be taken when defining a custom model in this range as it may override a public model for the account.

More details on the different ObjectID classes defined by the OMA for LwM2M can be found in the LwM2M Registry.

7.8.3.3.1. Public model

Objects from public range are managed by LiveObjects.

A (managed) public object definition :

  • has an empty owner attribute.

Public object definitions can’t be removed.

7.8.3.3.2. Custom model

A customer can extend the model by importing new Custom Object definitions.

This extension is called "Customer defined twin model". This model will apply for all twin devices of the customer account.

Using Twin Model Management API you can import a custom LWM2M OMA compatible XML Files, or delete a given customer model.

See this chapter for examples of Twin Model Management API usage which give you how to manage your custom objects.

7.8.3.3.3. Custom model limits

Some limits on custom models apply :

  • The number of custom model per tenant is limited.

7.8.4. Model API

7.8.4.1. Get Object-Definitions

Read TwinModels by giving an objectDefinitionId :

  • use urn:oma:lwm2m root element to list as children all LwM2M ObjectDefinitions.

  • use a urn:oma:lwm2m:oma:<Id>:<Version> format, and replace Id, Version to get a given LwM2M Object.

For example, urn:oma:lwm2m:oma:5:1.1 will get the Object Id=5 in Version=1.1.

7.8.4.1.1. Request

Endpoint:

GET /api/v1/deviceMgt/twin/model/object-definitions/{objectDefinitionId}

The usage is described here : Swagger API documentation.

HTTP Headers:

X-API-Key: <your API key>
Accept: application/json

Example:

GET /api/v1/deviceMgt/twin/model/object-definitions/urn:oma:lwm2m:oma:5:1.1
7.8.4.1.2. Response

HTTP Code:

200 OK

Body:

{
  "objectDefinitionId": "urn:oma:lwm2m:oma:5:1.1",
  "pathSegment": "5",
  "name": "Firmware Update",
  "description": "Firmware Update Object",
  "minOccurs": 0,
  "maxOccurs": 1,
  "type": "OBJECT_MAP",
  "operations": [
    "READ",
    "WRITE"
  ],
  "attributes": [
    [.../...]
    {
      "pathSegment": "6",
      "name": "PkgName",
      "description": "Package name",
      "minOccurs": 0,
      "maxOccurs": 1,
      "type": "STRING",
      "operations": [
        "READ"
      ]
    },
    [.../...]
  ],
  "parent": "urn:oma:lwm2m"
}
7.8.4.2. Post Object-Definitions

Import an ObjectDefinition (a custom Twin Model) :

  • set LWM2M format,

  • provide an OMA Compatible XML File,

  • decide whether the definition should be overwritten or not if it already exists.

7.8.4.2.1. Request

Endpoint:

POST /api/v1/deviceMgt/twin/model/object-definitions?inputFormat=lwm2m&override=true

The usage is described here : Swagger API documentation.

HTTP Headers:

X-API-Key: <your API key>
Accept: application/json

Body (form-data):

file: <XML File>
7.8.4.2.2. Response

HTTP Code:

201 Created

Body:

{
    "objectDefinitionId": "urn:oma:lwm2m:ext:33442",
    "pathSegment": "33442",
    "name": "LwM2M v1.1 Test Object CUSTOM CUSTOM",
    "description": "This object is created by the customer.",
    "minOccurs": 0,
    "maxOccurs": 0,
    [.../...],
    "parent": "urn:oma:lwm2m",
    "owner": "6139d13394f6b376e447ff9d"
}
Notice that the imported model owner attribute is the customer id.
7.8.4.3. Delete Object-Definitions

Remove an ObjectDefinition (a custom Twin Model) :

  • provide an ObjectDefinitionId.

7.8.4.3.1. Request

Endpoint:

DELETE /api/v1/deviceMgt/twin/model/object-definitions/{objectDefinitionId}

The usage is described here : Swagger API documentation.

HTTP Headers:

X-API-Key: <your API key>
Accept: application/json
7.8.4.3.2. Response

HTTP Code:

204 No content :imagesDir: lo_manual_v2/lwm2m_main/lwm2m_twin/images

7.8.5. DeviceTwin

LiveObjects DeviceTwin is a Twin representation of the real device:

  • which objects are supported

  • which objects are instantiated

  • which are the instantiated objects last reported attributes values

DeviceTwin overview

Interactive

A DeviceTwin includes :

  • supportedObjects as a list of objectDefinitionId : list Object definitions supported by the device.

  • instantiatedObjects as a list of Object : list of Object implemented by the device.

  • reportedValues as a list of AttributeValue : list of Attributes values reported by the device

In addition, LiveObjects provides three ways to represents a given DeviceTwin :

7.8.5.1. RootObject

RootObject is represented by the following :

Field Value Comment

objectDefinitionId

urn:oma:lwm2m

Parent of the ObjectDefinition identifier.

path

/

Root path

children

[]

Children Object

7.8.5.2. Object

Object is represented by the following :

Field Value Comment

objectDefinitionId

urn:oma:lwm2m:5:1.1

ObjectDefinition identifier.

path

/5

Object path : object (OBJECT_MAP) 5

instances

[]

List of ObjectInstance

7.8.5.3. ObjectInstance

ObjectInstance is represented by the following :

Field Value Comment

objectDefinitionId

urn:oma:lwm2m:5:1.1

ObjectDefinition identifier.

path

/5/0

Object path : object (OBJECT_MAP) 5 instance 0

attributes

[]

List of Attribute

7.8.5.4. Attribute

Attribute is represented by the following :

Field Value Comment

path

/5/0/3

Attribute path : object 5 instance 0 attribute 3. A root Object has an empty path.

/1/4/25/0

Attribute path : object 1 instance 4 multi-instances attribute 25 instance 0.

content

AttributeValue

Single instance attribute

contents

List<AttributeValue>

Multi-instances attributes

When an attribute is a single-instance attribute, his value is reported as content, whereas a multi-instances attribute is reported as contents. ==== DeviceTwin API

7.8.5.5. Get supported objects

Read DeviceTwin supported objects.

7.8.5.5.1. Request

Endpoint:

GET /api/v1/deviceMgt/devices/{deviceId}/twin/supported-objects

HTTP Headers:

X-API-Key: <your API key>
Accept: application/json

Example:

GET /api/v1/deviceMgt/devices/urn:lo:nsid:lwm2m:mydevice/twin/supported-objects
7.8.5.5.2. Response

HTTP Code:

200 OK

Body:

["urn:oma:lwm2m:oma:1", "urn:oma:lwm2m:oma:2", "urn:oma:lwm2m:oma:3", "urn:oma:lwm2m:oma:4", "urn:oma:lwm2m:oma:5:1.1"]

This response is the list of supported object definition identifiers for a DeviceTwin.

7.8.5.6. Get instantiated objects

Read DeviceTwin instantiated objects.

7.8.5.6.1. Request

Endpoint:

GET /api/v1/deviceMgt/devices/{deviceId}/twin/objects

Query parameters:

Name Description

expand

Optional. If 1 then children objects are expanded with their instances. 0 by default

HTTP Headers:

X-API-Key: <your API key>
Accept: application/json

Example:

GET /api/v1/deviceMgt/devices/urn:lo:nsid:lwm2m:mydevice/twin/objects?expand=1
7.8.5.6.2. Response

HTTP Code:

200 OK

Body:

{
    "objectDefinitionId": "urn:oma:lwm2m",
    "path": "/",
    "children": [
        {
            "objectDefinitionId": "urn:oma:lwm2m:oma:1",
            "path": "/1",
            "instances": [
                {
                    "objectDefinitionId": "urn:oma:lwm2m:oma:1",
                    "path": "/1/0"
                },
                {
                    "objectDefinitionId": "urn:oma:lwm2m:oma:1",
                    "path": "/1/1"
                }
            ]
        },
        {
            "objectDefinitionId": "urn:oma:lwm2m:oma:2",
            "path": "/2",
            "instances": [
                {
                    "objectDefinitionId": "urn:oma:lwm2m:oma:2",
                    "path": "/2/0"
                },
                {
                    "objectDefinitionId": "urn:oma:lwm2m:oma:2",
                    "path": "/2/1"
                }
            ]
        },
        {
            "objectDefinitionId": "urn:oma:lwm2m:oma:3",
            "path": "/3",
            "instances": [
                {
                    "objectDefinitionId": "urn:oma:lwm2m:oma:3",
                    "path": "/3/0"
                }
            ]
        }
    ]
}

This response is a RootObject with the list of children objects (instantiated objects) for a DeviceTwin.

7.8.5.7. Get detailed object

Read DeviceTwin detailed object.

7.8.5.7.1. Request

Endpoint:

GET /api/v1/deviceMgt/devices/{deviceId}/twin/objects/{objectId}

Query parameters:

Name Description

expand

Optional. If 1 then instances are expanded with their attributes having reported values. 0 by default

HTTP Headers:

X-API-Key: <your API key>
Accept: application/json

Example:

GET /api/v1/deviceMgt/devices/urn:lo:nsid:lwm2m:mydevice/twin/objects/1?expand=1
7.8.5.7.2. Response

HTTP Code:

200 OK

Body:

{
    "objectDefinitionId": "urn:oma:lwm2m:oma:1",
    "path": "/1",
    "instances": [
        {
            "objectDefinitionId": "urn:oma:lwm2m:oma:1",
            "path": "/1/0",
            "attributes": [
                {
                    "pathSegment": "5",
                    "path": "/1/0/5",
                    "content": {
                        "reportedValue": "1",
                        "timestamp": "2021-09-30T09:25:06.687Z"
                    }
                },
                {
                    "pathSegment": "25",
                    "path": "/1/0/25",
                    "contents": [
                        {
                            "reportedValue": "v1/1.1.2",
                            "timestamp": "2021-11-15T17:14:06.687Z",
                            "path": "/1/0/25/0"
                        },
                        {
                            "reportedValue": "v1/1.BIS",
                            "timestamp": "2021-11-15T17:14:06.687Z",
                            "path": "/1/0/25/1"
                        }
                    ]
                }
            ]
        },
        {
            "objectDefinitionId": "urn:oma:lwm2m:oma:1",
            "path": "/1/1",
            "attributes": [
                {
                    "pathSegment": "3",
                    "path": "/1/1/3",
                    "content": {
                        "reportedValue": "1",
                        "timestamp": "2021-09-30T09:25:06.687Z"
                    }
                }
            ]
        }
    ]
}

This response is an Object (instantiated objects and reported values) for a DeviceTwin.

7.8.5.8. Get detailed object instance

Read DeviceTwin detailed object instance.

7.8.5.8.1. Request

Endpoint:

GET /api/v1/deviceMgt/devices/{deviceId}/twin/objects/{objectId}/{instanceId}

HTTP Headers:

X-API-Key: <your API key>
Accept: application/json

Example:

GET /api/v1/deviceMgt/devices/urn:lo:nsid:lwm2m:mydevice/twin/objects/1/0
7.8.5.8.2. Response

HTTP Code:

200 OK

Body:

{
    "objectDefinitionId": "urn:oma:lwm2m:oma:1",
    "path": "/1/0",
    "attributes": [
        {
            "pathSegment": "5",
            "path": "/1/0/5",
            "content": {
                "reportedValue": "1",
                "timestamp": "2021-09-30T09:25:06.687Z"
            }
        },
        {
            "pathSegment": "25",
            "path": "/1/0/25",
            "contents": [
                {
                    "reportedValue": "v1/1.1.2",
                    "timestamp": "2021-11-15T17:14:06.687Z",
                    "path": "/1/0/25/0"
                },
                {
                    "reportedValue": "v1/1.BIS",
                    "timestamp": "2021-11-15T17:14:06.687Z",
                    "path": "/1/0/25/1"
                }
            ]
        }
    ]
}

This response is an ObjectInstance (instantiated object and reported values) for a DeviceTwin. :imagesDir: lo_manual_v2/lwm2m_main/lwm2m_twin/images

7.8.6. Operations

LiveObjects Twin operation is a representation of a real operation on a device:

  • READ - order the device to report some attributes,

  • WRITE - update or replace some object attributes values,

  • EXECUTE - execute some attributes.

  • WRITE-METADATA - update metadata (set, update, reset).

7.8.6.1. Operation definition

A Twin operation applies to a given device, includes a given type (read,write,execute, write-metadata), with some operation attributes (paths, values, options) and has a unique id (generated by LiveObjects).

Each operation orders a given action (or composite action) on a target device and the result of this action is visible within operation status and operation error attributes.

Example of Twin Operation:

    {
        "id": "b50d094e520a4d58ad367f2fb9afdf6f",
        "type": "READ",
        "paths": [
            "/1/0/0"
        ],
        "status": "OK",
        "created": "2022-03-07T16:03:51.609Z",
        "updated": "2022-03-07T16:04:09.263Z"
    }

This is a success and done READ operation.

Field Value Comment

id

b50d094e520a4d58ad367f2fb9afdf6f

Operation unique id, generated by LiveObjects

type

READ

Type of the operation.

paths

['/1/0/0', '/5/1/3']

Target paths of related device objects or attributes

values

[{"path":"/1/0/3", "value":"x"},
 {"path":"/5/0/3", "value":"y"}]

for WRITE and WRITE-METADATA: Values to set.

writeMode

REPLACE

for WRITE: mode to set. Possible values : UPDATE, REPLACE

contextToken

OPBIS123

Free custom tag on the operation

status

OK

Current status of Twin Operation

options

{"lwm2m": {"contentFormat": {"response": "SENML_JSON"} } }

Options of Twin Operation, cf. Operation options section.

policy.attempts

1

Number of attempts allowed for this operation (default value is 1 that means there is no retry).

error.code

OPERATION_INVALID

status FAILED only: Error code of Twin Operation.

error.details

details here

status FAILED only: Error details of Twin Operation.

error.deviceCode.value

404

status FAILED, error.code DEVICE_ERROR only: Device error value.

error.deviceCode.reason

404 not found

status FAILED, error.code DEVICE_ERROR only: Device error reason.

created

2022-02-24T16:30:06.687Z

When the operation were created.

updated

2022-02-24T17:01:00.122Z

When the operation were updated. In case of status OK, this is when the device responds.

======= WRITE-METADATA Operation details

Live Objects supports all LwM2M 1.1 notification attributes (named metadata in current chapter).

Those metadata define the conditions when notification on an objet or attribute is sent.

metadata Description

pmin

The Minimum Period metadata indicates the minimum time in seconds the LwM2M Client MUST wait between two notifications

pmax

The Maximum Period metadata indicates the maximum time in seconds the LwM2M Client MAY wait between two notifications

gt

This Greater Than metadata defines a threshold high value. When this metadata is present, the LwM2M Client MUST notify the Server each time the Observed Attribute value crosses this threshold

lt

This Less Than metadata defines a threshold low value. When this metadata is present, the LwM2M Client MUST notify the Server each time the Observed Attibute value crosses this threshold

st

This Step metadata defines a minimum change value between two notifications

epmin

The Minimum Evaluation Period metadata indicates the minimum time in seconds the LwM2M Client MUST wait between two evaluations of reporting criteria

epmax

The Maximum Evaluation Period metadata indicates the maximum time in seconds the LwM2M Client MAY wait between two evaluations of reporting criteria

7.8.6.2. Operation options

Operation options apply on the following use-cases:

Scope Key Possible values Comment

Lwm2m operation

lwm2m.contentFormat

TLV, JSON, SENML_JSON, SENML_CBOR, TEXT, OPAQUE, CBOR

content format requested by the customer for the operation (request, response)

7.8.6.3. Operation examples
Name Operation extract Details

READ all objects

{
   "type":"READ",
   "paths":["/"]
}

Read all objects

READ one object

{
   "type":"READ",
   "paths":["/5"]
}

Read object 5

READ one object instance

{
   "type":"READ",
   "paths":["/5/0"]
}

Read object 5 instance 0

READ one attribute

{
   "type":"READ",
   "paths":["/5/0/3"]
}

Read object 5 instance 0 attribute 3

READ one multi-instances attribute instance

{
  "type":"READ",
  "paths":["/1/4/11/4"]
}

Read object 1 instance 4 attribute 11 attribute instance 4

READ composite two objects, and one multi-instances attribute instance

{
   "type":"READ",
   "paths":["/3","/5","/1/4/11/4"]
}

Read objects 3, 5 and an attribute instance /1/4/11/4

WRITE one attribute in update mode

{
   "type":"WRITE",
   "writeMode":"UPDATE",
   "paths":["/1/0"],
   "values":[
       {"path":"/1/0/7", "value":"sample1"}
   ]
}

Write sample1 into object 1 instance 0 attribute 7. An WRITE operation requires one and only one path value in paths.

WRITE one multi-instances attribute instance in update mode

{
   "type":"WRITE",
   "writeMode":"UPDATE",
   "paths":["/1/4"],
   "values":[
       {"path":"/1/4/11/4", "value":"sample2"}
   ]
}

Write sample2 into attribute instance /1/4/11/4

WRITE two multi-instances attribute instances in update mode

{
   "type":"WRITE",
   "writeMode":"UPDATE",
   "paths":["/1/0/11"],
    "values":[
      {"path":"/1/0/11/0", "value":"sampleA"},
      {"path":"/1/0/11/2", "value":"sampleB"}]
}

Write sampleA into attribute instance /1/0/11/0, and sampleB into attribute instance /1/0/11/2

WRITE two multi-instances attribute instances in replace mode

{
   "type" : "WRITE",
   "writeMode":"REPLACE",
   "paths":["/1/0/11"],
   "values" : [
      { "path": "/1/0/11/0", "value":"sampleA" },
      { "path": "/1/0/11/2", "value":"sampleB" }
   ]
}

Write target /1/0/11 in replace mode : write sampleA into attribute instance /1/0/11/0, and write sampleB into attribute instance /1/0/11/2, and remove other /1/0/11 attributes.

WRITE multiple attributes on object instance in update mode

{
  "type":"WRITE",
  "writeMode":"UPDATE",
  "paths":["/1/0"],
  "values":[
     { "path": "/1/0/7", "value":"sampleD" },
     { "path": "/1/0/11/2", "value":"sampleE" },
     { "path": "/1/0/11/0", "value":"sampleF" }
  ]
 }

Write in update mode /1/0/7, /1/0/11/2, /1/0/11/0 values, and only them.

WRITE multiple attributes on object instance in replace mode

{
  "type": "WRITE",
  "writeMode":"REPLACE",
  "paths": [ "/1/0" ],
  "values":[
     { "path": "/1/0/7", "value":"sampleD" },
     { "path": "/1/0/11/2", "value":"sampleE" },
     { "path": "/1/0/11/0", "value":"sampleF" }
  ]
}

Write /1/0 in replace mode : set /1/0/7, /1/0/11/2, /1/0/11/0 values, and remove other /1/0 attributes.

WRITE composite multiple attributes on different objects in update mode

{
  "type": "WRITE",
  "writeMode":"UPDATE",
  "paths": [ "/" ],
  "values":[
      { "path": "/2/1/6", "value":"sampleX" },
      { "path": "/1/0/7", "value":"sampleY" },
      { "path": "/1/0/4/1", "value":"sampleZ" }
  ]
}

Write in update mode /2/1/6, /1/0/7, /1/0/4/1 values, and only them. It’s a composite WRITE because target paths scope different objects instances : /2/1 and /1/0

WRITE composite multiple attributes on different object instances

{
  "type": "WRITE",
  "writeMode":"UPDATE",
  "paths": [ "/" ],
  "values":[
     { "path": "/1/0/7", "value":"sampleV" },
     { "path": "/1/1/7", "value":"sampleW" }
  ]
}

Write in update mode /1/0/7, /1/1/7 values, and only them. It’s a composite WRITE because target paths scope different objects instances : /1/0 and /1/1

EXECUTE execute a given attribute

{
  "type": "EXECUTE",
  "paths" : [ "/1/0/8" ]
}

Execute /1/0/8 attribute. An EXECUTE operation requires one and only one path value in paths.

WRITE-METADATA update metadata

{
  "type": "WRITE-METADATA",
  "values": [
    {
      "path": "/1/0/7",
      "metadata": [
        {
          "name": "pmin",
          "value": "20"
        },
        {
          "name": "gt",
          "value": "50"
        },
        {
          "name": "lt"
        }
      ]
    }
  ]
}

Update metadata on /1/0/7 (set or update pmin and gt and reset lt metadata)

A WRITE-METADATA operation requires one and only one path that could identify an object, an object instance, an attribute or an attribute instance.

7.8.6.4. Operation lifecycle

A Twin operation is created using API and the result of an operation will be available via API too.

Once created, the operation is executed asynchronous as soon as the device become twin capable (ex. the device connect and his interface become online).

TwinOperation sequence diagram

Interactive

API allow to monitor the status of the operation waiting for a final state by using a given operation id, and polling the GET API.

TwinOperation status and state machine

Interactive

status Comment

PENDING

Operation is created and ready to be sent.

SENT

Operation has been emitted from Twin Service to the connector then the device.

RETRYING

Operation didn’t succeed but the reason of the error allows a retry.

CANCELLED

A pending operation has been cancelled by user (via API). It is a final state.

EXPIRED

A pending or sent operation has remained in the same state for too long. It is a final state.

FAILED

For some reason, the operation didn’t succeed. The reason why it failed is described by error fields. It is a final state.

OK

Operation succeed. It is a final state.

The following expiration delay applies:

origin status Schema reference Comment

from PENDING

x

If a device never registers, a PENDING operation moves to EXPIRED after 3 days.

from SENT

y

If a response is not received after 25 minutes, a SENT operation moves to RETRYING if max attempt is not reached else the SENT operation moves to EXPIRED.

from RETRYING

x

If a device never registers, a RETRYING operation moves to EXPIRED after 3 days.

7.8.6.5. Operation retry policy

For errors that are considered as unrecoverable (e.g device rejected the request), there will be only one attempt to send an operation.

For other errors there will be additional attempts limited to the number of attempts provided by the end user. For instance, we can mention a 5xx response or a time-out.

The operation is executed asynchronously as soon as the device becomes twin capable (ex. the device connects and its interface becomes online).

TwinOperation retrying sequence diagram

Interactive

7.8.6.6. Operation limits

Some limits apply in terms of :

  • actives operations per device : operations having PENDING, SENT, RETRYING status. Other this limit, an operation creation attempt will fail (with 403 status).

  • final operations per device : operations having UNKNOWN, CANCELLED, EXPIRED, FAILED or OK status. Other this limit, at creation of new operation time, older operations will be removed. ==== Operations API

This section includes API call examples for the Twin Operations management.

7.8.6.7. Create an operation

Create a new DeviceTwin operation.

According to the operation lifecycle, this will create a PENDING operation.

Different kinds of Twin operation are described by twin operation definition and twin operation examples.

Example:

POST /api/v1/deviceMgt/devices/urn:lo:nsid:lwm2m:mydevice/twin/operations
{
"type":"READ",
"paths":["/1/0"],
"contextToken" : "this is a simple READ"
}

Response

201 CREATED
{
    "id": "f9b9877c7679454ea56e568b31ee7c48",
    "type": "READ",
    "paths": [
        "/1/0"
    ],
    "contextToken": "this is a simple READ",
    "status": "PENDING",
    "created": "2022-02-25T09:32:55.248Z",
    "updated": "2022-02-25T09:32:55.248Z"
}

A pending DeviceTwin READ instance /1/0 operation has been created.

7.8.6.8. Cancel a pending operation

Cancel a PENDING DeviceTwin operation.

Example:

PUT /api/v1/deviceMgt/devices/urn:lo:nsid:lwm2m:mydevice/twin/operations/f2ed1637ec10466089064804ed68e351/status
"CANCELED"

Response

200 OK

This response confirm that Twin Operation status has been set to CANCELED.

7.8.6.9. Get an operation

Get one DeviceTwin operation.

Example:

GET /api/v1/deviceMgt/devices/urn:lo:nsid:lwm2m:mydevice/twin/operations/a1ca9551754d48d09e31fd30d36b88d1

Response

200 OK
{
    "id": "a1ca9551754d48d09e31fd30d36b88d1",
    "type": "READ",
    "paths": [
        "/1/0"
    ],
    "contextToken": "ABC123",
    "status": "OK",
    "created": "2022-02-11T16:16:05.073Z",
    "updated": "2022-02-11T16:16:23.492Z"
}

This is a Twin Operation details.

7.8.6.10. List operations

List DeviceTwin operations.

Some filter could apply to restrict the results :

parameter description

status

<list> restrict to operations having this status

contextToken

restrict to operations having this contextToken (exact match)

type

<list> restrict to operations having this type

path

restrict to operations having at least one time this path in his definition (exact match)

Number of result is constraint by Twin operations limits.

Example:

GET /api/v1/deviceMgt/devices/urn:lo:nsid:lwm2m:mydevice/twin/operations?status=OK&status=FAILED&status=EXPIRED&type=READ

Response

200 OK
[
    {
        "id": "f2ed1637ec10466089064804ed68e351",
        "type": "READ",
        "paths": [
            "/1/0"
        ],
        "contextToken": "ABC123",
        "status": "OK",
        "created": "2022-02-11T16:16:05.073Z",
        "updated": "2022-02-11T16:16:23.492Z"
    },
    {
        "id": "25a65010ab9b4c38a925c2dc7f16a7c8",
        "type": "READ",
        "paths": [
            "/1/0/200",
            "/1/0/7"
        ],
        "status": "FAILED",
        "error": {
            "code": "OPERATION_INVALID",
            "details": "The details here"
        },
        "created": "2022-02-16T15:20:24.142Z",
        "updated": "2022-02-16T15:20:34.252Z"
    }
 ]

This response is the list of Twin Operations of a DeviceTwin

  • having status in [OK, FAILED, EXPIRED],

  • having type in [READ]. :imagesDir: lo_manual_v2/lwm2m_main/lwm2m_twin/images

7.8.7. Observations

7.8.7.1. Observation definition

An Observation allows Live Objects to be notified when some Attributes change on the device. It can target:

  • a specific Attribute

  • an Object Instance

  • all Object Instances of an Object

  • several Attributes (Observation Composite)

Example of an Observation targeting an Object Instance:

{
    "id": "631f1190d4135d0066541e8b",
    "paths": [
        "/6/0"
    ],
    "status": "PENDING",
    "name": "Observation on the location Object",
    "created": "2022-09-12T11:02:29.811Z"
}
Field Example Comment

id

631f1190d4135d0066541e8b

Observation unique id, generated by Live Objects

paths

['/6/0']

Target paths of related device objects or attributes to observe

status

PENDING

Current status of the Observation among PENDING, OBSERVING and FAILED

name

Observation on the location Object

User-defined name for the Observation

created

2022-09-12T11:02:29.811Z

Observation creation date

7.8.7.2. Observation Lifecycle

An Observation is created using the API and its status will be available via the API too.
Once created, the Observation is sent immediately if the device is ONLINE or the next time the device sends an Update or Register otherwise.
Depending on the type of error, Observations that have failed can be automatically re-sent at the next Update. The number of attempts is nevertheless limited.
When a LwM2M device goes offline (de-registration or the lifetime of the registration expires), the Observations on Live Objects for this device go back to the PENDING state. They will be automatically re-sent when the device sends a Register, regardless of their status.
An Observation can be cancelled. Upon the user cancellation request, a Cancel Observation operation is sent to the device if it is ONLINE. Otherwise, the cancellation occurs at the next Notify.

Observation sequence diagram

Interactive

Observation state machine

Interactive

status Comment

PENDING

The Observation has been created and is ready to be sent.

FAILED

The Observation has not succeeded after the maximum number of attempts.

OBSERVING

The Observation is active on the device.

7.8.7.3. Observation retry policy

For errors that are considered as unrecoverable, there will be only one attempt to send an Observation. The following errors fall in this category:

  • The device responded with a 4xx code

  • The device rejected the request

For other errors there will be 5 attempts. For instance, we can mention a 5xx response or a time-out.

7.8.7.4. Observation configuration

The parameters related to an Observation can be configured by the Write-Metadata operation.

7.8.7.5. Observation limits

The number of Observations per device is limited regardless of their status.

7.8.8. Observations API

This section includes API call examples for the Observations management.

7.8.8.1. Create an Observation

Create a new Observation.

According to the Observation lifecycle, this will create a PENDING Observation.

Example:

POST /api/v1/deviceMgt/devices/urn:lo:nsid:lwm2m:mydevice/twin/observations
{
    "paths": [
        "/6/0"
    ],
    "name": "Observation on the location Object"
}

Response

201 CREATED
{
    "id": "631f1190d4135d0066541e8b",
    "paths": [
        "/6/0"
    ],
    "status": "PENDING",
    "name": "Observation on the location Object",
    "created": "2022-09-12T11:02:29.811Z"
}

A pending Observation has been created.

7.8.8.2. Cancel an Observation

Cancel an Observation.

Example:

DELETE /api/v1/deviceMgt/devices/urn:lo:nsid:lwm2m:mydevice/twin/observations/631f1190d4135d0066541e8b

Response

204 NO CONTENT

This response confirm that the Observation has been removed and will be cancelled on the device.

7.8.8.3. Get an Observation

Get one Observation.

Example:

GET /api/v1/deviceMgt/devices/urn:lo:nsid:lwm2m:mydevice/twin/observations/631f1190d4135d0066541e8b

Response

200 OK
{
    "id": "631f1190d4135d0066541e8b",
    "paths": [
        "/6/0"
    ],
    "status": "OBSERVING",
    "name": "Observation on the location Object",
    "created": "2022-09-12T11:02:29.811Z"
}

This is an Observation details.

7.8.8.4. List Observations

List Observations.

The number of result is constraint by Twin Observations limits.

Example:

GET /api/v1/deviceMgt/devices/urn:lo:nsid:lwm2m:mydevice/twin/observations

Response

200 OK
[
    {
        "id": "62d6c3230d0685589727902e",
        "paths": [
            "/3303/0"
        ],
        "status": "FAILED",
        "name": "Observation on the temperature Object",
        "created": "2022-07-19T14:43:47.023Z"
    },
    {
        "id": "631f1190d4135d0066541e8b",
        "paths": [
            "/6/0"
        ],
        "status": "OBSERVING",
        "name": "Observation on the location Object",
        "created": "2022-09-12T11:02:29.811Z"
    }
]

This response is the list of Observations of a DeviceTwin :imagesDir: lo_manual_v2/lwm2m_main/lwm2m_twin/images

7.8.9. DataRules

LiveObjects Twin data rule is a representation of a rule that can be used to trigger a new data message from device reported values.

7.8.9.1. DataRule definition

A Twin data rule applies to a given tenant, includes a given type, with some rule attributes (paths) and has a unique id (generated by LiveObjects).

A tenant data rule presence drives the way twin message will be generated.

Twin data rule type are:

  • PASSTHROUGH - order twin to forward all values that match paths as new data message.

Example of Twin data rule:

    {
        "id": "6250072f5297c340e68f7bad",
        "name": "my passthrough",
        "type": "PASSTHROUGH",
        "paths": [
            "/"
        ],
        "created": "2022-04-08T09:58:07.843Z"
    }

This is a PASSTHROUGH data rule that triggers all values (having path starting with /).

Field Value Comment

id

6250072f5297c340e68f7bad

Data rule unique id, generated by LiveObjects

type

PASSTHROUGH

Type of the rule.

paths

['/']

Target paths of related rule

created

2022-04-08T09:58:07.843Z

When the rule were created.

7.8.9.2. Data rules limits

For now, you can only create one PASSTHROUGH rule for your tenant.

7.8.10. Data rules API

Data rules management API are available at following endpoint: /api/v1/deviceMgt/twin/data/rules and are documented on Swagger. :imagesDir: lo_manual_v2/lwm2m_main/lwm2m_twin/images

7.8.11. Data Message

When a LWM2M device reports value changes, a data message that includes this change is generated by LiveObjects under certain conditions:

  • the report must be at the device initiative (send, or notify but not read response),

  • the report must match a given data rule of the tenant.

When all these conditions are met, a message is generated.

Today the generation model used for the message is twin_json.

7.8.11.1. DataMessage common attributes

A Twin data message as other LiveObjects messages, will embed some common attributes: id, streamId, etc.

The value part of the message will embed the device reported values representation, depending on the model used.

Example of a fill Twin data message having twin_json model:

{
  "id": "6254192e1a52727da422dfdf",
  "streamId": "urn:lo:nsid:lwm2m:simulator",
  "timestamp": "2022-04-11T12:03:58.695Z",
  "model": "twin_json",
  "value": {
    "device": {
      "0": {
        "deviceType": "Demo",
        "utcOffset": "Z",
        "serialNumber": "LT-500-000-0001",
        "timezone": "Etc/UTC",
        "memoryFree": 6278,
        "errorCode": {
          "0": 0
        },
        "supportedBindingAndModes": "U",
        "manufacturer": "Leshan Demo Device",
        "currentTime": "2022-04-11T12:03:58Z",
        "batteryStatus": 6,
        "memoryTotal": 19400,
        "modelNumber": "Model 500",
        "hardwareVersion": "1.0.1",
        "firmwareVersion": "1.0.0",
        "softwareVersion": "1.0.2",
        "batteryLevel": 44
      }
    }
  },
  "tags": [
    "lwm2m-simulator",
  ],
  "extra": {},
  "metadata": {
    "source": "urn:lo:nsid:lwm2m:simulator",
    "group": {
      "id": "root",
      "path": "/"
    },
    "connector": "lwm2m",
    "network": {
      "lwm2m": {
        "ep": "urn:lo:nsid:lwm2m:simulator"
      }
    }
  },
  "created": "2022-04-11T12:03:58.725Z"
}

This message is generated by the urn:lo:nsid:lwm2m:simulator lwm2m endpoint and embed a twin_json representation of some device instance 0 attributes (reported values).

7.8.11.2. DataMessage TWIN_JSON format

A TWIN_JSON data message is a JSON representation of reported values that include camel case human-readable entity names.

In a TWIN_JSON data message, each value is embedded in an object, plus an attribute container.

Reminder: Object, Attribute definitions are part of the TwinModel.

For a simple attribute the JSON message will be generated according the following design:

  • camel case name of the object,

  • pathSegment id of the object,

  • camel case name of the attribute,

  • reported raw value of the attribute.

For example, for a given [/3/0/1, /3/0/9] reported values, associated twin model definitions are:

  • Object 3 : Device - Instance 0

  • Attribute 1: Model Number.

  • Attribute 9: Battery Value.

Related TWIN_JSON of these values will be:

{
  "device": {
    "0": {
      "modelNumber": "Model 500",
      "batteryLevel": 44
    }
  }
}
7.8.11.3. DataMessage metadata enrichment

A Twin data message as other LiveObjects messages, may embed some metadata.

They are extracted from reported values.

Currently, extracted metadata are:

Metadata Description Source Target

location

location of the device

\6\0\0 to \6\0\3

Object 6 : Location - Instance 0

  • Attribute 0: Latitude

  • Attribute 1: Longitude

  • Attribute 2: Altitude

  • Attribute 3: Radius (Accuracy)

see location provided by the device chapter

8. Device management

8.1. Device group

8.1.1. Principle

A group enables to bring devices together. Groups can be used to :

  • ease browsing and sorting on Live Objects web portal.

  • using inventory explorer, count and aggregate your devices fleet, select a sub set (group) of your devices fleet by criterias to manage it.

  • apply different forwarding rules on the data collected from the devices (Cf. "Notifications" section).

  • apply different event processing and alarming rules (Cf. "Alarming" chapter).

Groups behave mostly like directories in a filesystem (considering devices are files): a Group can include other groups and devices. For instance a device can only belong to one group at a time. There are however some exceptions to this analogy (see group deletion rules).

Each tenant has a default root group. A group, except root group, must have a parent group and can have subgroups. In the same tenant, the complete path of each group must be unique but several groups can have the same local identifier (pathNode). The complete path enables to have the tree view of your group.

Group object model:

JSON Params Description

id

group unique identifier

pathNode

Optional. local group id in path

path

complete group path

parentId

Optional. parent group identifier

description

Optional. detailed description of the group

created

creation date of the device

updated

last update date of the device

The group id is fixed, but the group path is calculated because he depends on both the pathNode and the location of the group in the tree. Moving a group in the tree logically leads to a modification of the group path.

Example:

{
    "id": "u1z1k8",
    "pathNode": "lyon",
    "path": "/france/lyon",
    "parentId": "P2112f",
    "description": "City of Lyon",
    "created": "2018-02-14T16:53:54.515Z",
    "updated": "2018-02-14T16:53:54.515Z"
}
Groups tree view

Interactive

8.1.2. Create a new group

8.1.2.1. Request

Endpoint:

POST /api/v1/deviceMgt/groups

HTTP Headers:

X-API-Key: <your API key>
Content-Type: application/json
Accept: application/json

Body:

JSON Params Description

pathNode

group local identifier in path (unique for groups with the same parent)

parentId

Optional. reference to group parent (id). Root group by default.

description

Optional. detailed description of the group

Example:

POST /api/v1/deviceMgt/groups
{
    "pathNode":"lyon",
    "parentId":"P2112f",
    "description":"City of Lyon"
}
8.1.2.2. Response

HTTP Code:

201 CREATED

Body:

Error case:

HTTP Code Error code message

400

GENERIC_INVALID_PARAMETER_ERROR

The submitted parameter is invalid.

401

UNAUTHORIZED

Authentication failure.

403

GENERIC_ACTION_FORBIDDEN_ERROR

Request forbidden.

404

DM_GROUP_NOT_FOUND

Group not found

409

DM_GROUP_DUPLICATE

Conflict on group path

Example:

{
    "id": "u1z1k8",
    "pathNode": "lyon",
    "path": "/france/lyon",
    "parentId": "P2112f",
    "description": "City of Lyon",
    "created": "2018-02-14T16:53:54.515Z",
    "updated": "2018-02-14T16:53:54.515Z"
}

8.1.3. Update a group

The path change of a group does not change its content (Devices, Groups).

8.1.3.1. Request

Endpoint:

PUT /api/v1/deviceMgt/groups/<id>

HTTP Headers:

X-API-Key: <your API key>
Content-Type: application/json
Accept: application/json

Body:

JSON Params Description

pathNode

Optional. group local id in path (unique for groups with the same parent)

parentId

Optional. reference to group parent (id). Root group by default

description

Optional. detailed description of the group

Example:

PUT /api/v1/deviceMgt/groups/u1z1k8
{
    "pathNode":"paris",
    "parentId":"P2112f",
    "description":"City of Paris"
}
8.1.3.2. Response

HTTP Code:

200 OK

Body:

Error case:

HTTP Code Error code message

400

GENERIC_INVALID_PARAMETER_ERROR

The submitted parameter is invalid.

401

UNAUTHORIZED

Authentication failure.

403

GENERIC_ACTION_FORBIDDEN_ERROR

Request forbidden.

404

DM_GROUP_NOT_FOUND

Group not found

Example:

{
    "id": "u1z1k8",
    "pathNode": "paris",
    "path": "/france/paris",
    "parentId": "P2112f",
    "description": "City of Paris",
    "created": "2018-02-14T16:53:54.515Z",
    "updated": "2018-02-15T10:31:26.667Z"
}

8.1.4. List groups

8.1.4.1. Request

Endpoint:

GET /api/v1/deviceMgt/groups

Query parameters:

Name Description

limit

Optional. maximum number of groups in response. 20 by default.

offset

Optional. the number of entries to skip in the results list. 0 by default.

parentId

Optional. filter list by group’s parent. When a parent is set, only direct children are returned (one level).

groupPath

Optional. filter list by group’s path. When a full path is set, only nodes matching exactly this path are returned. In order to return nodes matching a path and all descendants, you must end the groupPath with /* (ex. /spain/*). In order to return direct children nodes -only- of a path, the groupPath must end with /*/ (ex. /spain/*/).

List Groups Query samples:

QueryParams Returned nodes

?groupPath=/france

/france

?groupPath=/*

/france, /france/lyon,/france/paris, /italia

?groupPath=/france/*

/france, /france/lyon,/france/paris

?groupPath=/france/*/

/france/lyon,/france/paris

?parentId=root

/france, /italia

?parentId=P2112f&groupPath=/*

/france/lyon,/france/paris

?parentId=P2112f&groupPath=/france/*

/france/lyon,/france/paris

?parentId=root&groupPath=/france/*

no result

HTTP Headers:

X-API-Key: <your API key>
Accept: application/json
X-Total-Count: <boolean>

For more info about X-Total-Count, see "API v1 paging" section.

Example:

GET /api/v1/deviceMgt/groups?limit=20&offset=0
8.1.4.2. Response

HTTP Code:

200 OK

Body:

Example:

[
    {
        "id": "root",
        "path": "/",
        "created": "2017-11-03T15:23:22.771Z",
        "updated": "2017-11-03T15:23:22.771Z"
    },
    {
        "id": "P2112f",
        "pathNode": "france",
        "path": "/france",
        "parentId": "root",
        "description": "",
        "created": "2018-02-14T16:47:37.318Z",
        "updated": "2018-02-14T16:47:37.318Z"
    },
    {
        "id": "u1z1k8",
        "pathNode": "paris",
        "path": "/france/paris",
        "parentId": "P2112f",
        "description": "City of Paris",
        "created": "2018-02-14T16:53:54.515Z",
        "updated": "2018-02-15T10:31:26.667Z"
    }
]

8.1.5. Get a group

8.1.5.1. Request

Endpoint:

GET /api/v1/deviceMgt/groups/<id>

HTTP Headers:

X-API-Key: <your API key>
Accept: application/json

Example:

GET /api/v1/deviceMgt/groups/u1z1k8
8.1.5.2. Response

HTTP Code:

200 OK

Body:

Error case:

HTTP Code Error code message

404

DM_GROUP_NOT_FOUND

Group not found

Example:

{
    "id": "u1z1k8",
    "pathNode": "paris",
    "path": "/france/paris",
    "parentId": "P2112f",
    "description": "City of Paris",
    "created": "2018-02-14T16:53:54.515Z",
    "updated": "2018-02-15T10:31:26.667Z"
}

8.1.6. Delete a group

You can’t delete a group which has devices.

8.1.6.1. Request

Endpoint:

DELETE /api/v1/deviceMgt/groups/<id>

HTTP Headers:

X-API-Key: <your API key>
Accept: application/json

Example:

DELETE /api/v1/deviceMgt/groups/u1z1k8
8.1.6.2. Response

HTTP Code:

204 NO CONTENT

Error case:

HTTP Code Error code message

400

GENERIC_INVALID_PARAMETER_ERROR

The submitted parameter is invalid.

401

UNAUTHORIZED

Authentication failure.

403

DM_GROUP_UNDELETABLE

Group can’t be deleted: contains devices or sub-groups

404

DM_GROUP_NOT_FOUND

Group not found

8.2. Configuration

Currently, APIs allow to manage configuration only for MQTT connector.

8.2.1. Principle

A device can declare one or many parameters: a parameter is identified by a string "key" and can take a typed value (binary, int32, uint32, timestamp).

Live Objects can track the changes of the current value of a device parameters, and allow users to set different target values for those parameters. Live Objects will then try to update the parameters on the device once it’s connected and available.

Device configuration sync steps

Interactive

  • (before) :

    • device initiates MQTT connection with Live Objects,

    • device subscribes in MQTT to a private topic, where it will receive later the configuration update requests,

  • step 0 : device notifies Live Objects that it is connected and available for configuration updates on a specific topic,

  • step 1 : device notifies Live Objects of its current configuration,

  • step 2 : Live Objects compares the current and target configuration for this device. If they differ:

    • step 3 : Live Objects sends to the device, on the topic indicated at step 0, the list of parameters to update, with their target value,

    • step 4 : device handles the request, and tries to apply the change(s),

    • step 5 : device respond to the change request with the new configuration,

    • step 6 : Live Objects saves the new configuration. Parameters that have been successfully updated now have the status "OK" and the others the status "FAILED".

Device configuration sync states

Interactive

If your device is connected in Device mode, please refer to the MQTT device mode part for messages that your device can send or receive.

8.2.2. Get device configuration parameters

To retrieve the details of the configuration map of the device we can use the GET API.

8.2.2.1. Request

Endpoint:

GET /api/v1/deviceMgt/devices/<deviceId>/config/parameters

HTTP Headers:

X-API-Key: <your API key>
Content-Type: application/json
Accept: application/json

Example:

GET /api/v1/deviceMgt/devices/urn:lo:nsid:sensor:temp001/config/parameters
8.2.2.2. Response

HTTP Code:

200 OK

Body:

For each parameter, the following information is available :

{
  "{paramKey}": {
    "reported": {
        "type": {paramType},
        "value": {paramValue},
        "timestamp": {timestampsValue}
    },
    "requested": {
        "type": {paramType},
        "value": {paramValue},
        "timestamp": {timestampsValue}
    },
    "syncStatus": {paramStatus}
}

With:

paramKey

string uniquely identifying the device configuration parameter

paramType

indicates the config parameter type between: INT32, UINT32, BINARY, STRING or FLOAT

paramValue

value requested for the parameter

timestampsValue

update date of the parameter

paramStatus

parameter update status: NONE, PENDING, SENT, CANCELED, OK or FAILED

The section reported is present when the device has answered and corresponds to parameter configuration returned by the device, the paramStatus could be OK or FAILED.

Error case:

HTTP Code Error code message

400

GENERIC_INVALID_PARAMETER_ERROR

The submitted parameter is invalid.

404

DM_DEVICE_NOT_FOUND

Device not found

Example:

{
  "param1" : {
    "requested" : {
      "type" : "INT32",
      "value" : 1,
      "timestamp" : "2018-08-23T08:10:01.029Z"
    },
    "syncStatus" : "PENDING"
  },
  "param2" : {
    "requested" : {
      "type" : "UINT32",
      "value" : 4321,
      "timestamp" : "2018-08-01T14:39:16.216Z"
    },
    "syncStatus" : "PENDING"
  },
  "param3" : {
    "reported" : {
      "type" : "FLOAT",
      "value" : 3.2,
      "timestamp" : "2018-04-26T08:16:33.681Z"
    },
    "requested" : {
      "type" : "FLOAT",
      "value" : 3.2,
      "timestamp" : "2019-06-17T12:52:20.930Z"
    },
    "syncStatus" : "OK"
  },
  "param4" : {
    "requested" : {
      "type" : "BINARY",
      "value" : 11001,
      "timestamp" : "2018-08-01T14:37:52.579Z"
    },
    "syncStatus" : "CANCELED"
  },
  "param5" : {
    "reported" : {
      "type" : "STRING",
      "value" : "my data",
      "timestamp" : "2018-03-29T08:48:20.810Z"
    },
    "requested" : {
      "type" : "STRING",
      "value" : "info",
      "timestamp" : "2018-03-29T08:48:20.813Z"
    },
    "syncStatus" : "FAILED"
  }
}

8.2.3. Set device configuration parameters

8.2.3.1. Request

Endpoint:

POST /api/v1/deviceMgt/devices/<deviceId>/config

HTTP Headers:

X-API-Key: <your API key>
Content-Type: application/json
Accept: application/json

Body:

JSON Params Description

parameters

list of device configuration update

notifyTo

Optional. topic where configuration change/sync events must be published to

Each parameter to update must have the following structure:

"{paramKey}": {
    "type": {paramType},
    "value": {paramValue}
}

With:

paramKey

a string uniquely identifying the device configuration parameter. Should not start with $ character

paramType

indicates the config parameter type between

"INT32"

the value must be an integer from -2,147,483,648 to 2,147,483,647,

"UINT32"

the value must a positive integer from 0 to 4,294,967,295,

"BINARY"

the value is a base64 encoded binary content,

"STRING"

the value is a UTF-8 string,

"FLOAT"

the value is float (64 bits) value.

Example:

POST /api/v1/deviceMgt/devices/urn:lo:nsid:sensor:temp001/config
{
    "parameters": {
        "MyParamINT32" : {
            "type" : "INT32",
            "value" : -333
        },
        "MyParamSTRING" : {
            "type" : "STRING",
            "value" : "My sentense"
        }
    },
    "notifyTo": "fifo/configUpdateFifo"
}
8.2.3.2. Response

HTTP Code:

200 OK

Error case:

HTTP Code Error code message

400

GENERIC_INVALID_PARAMETER_ERROR

The submitted parameter is invalid.

If the device does not exist, it will be auto-provisionned.

8.2.4. Get a description of the device configuration

8.2.4.1. Request

Endpoint:

GET /api/v1/deviceMgt/devices/<deviceId>/config

HTTP Headers:

X-API-Key: <your API key>
Content-Type: application/json
Accept: application/json

Example:

GET /api/v1/deviceMgt/devices/urn:lo:nsid:sensor:temp001/config
8.2.4.2. Response

HTTP Code:

200 OK

Body:

JSON Params Description

parameters

list of device configuration update

notifyTo

Optional. topic where configuration change/sync events must be published to

For each parameter, the following information is available :

{
  "parameters" : {
      "{paramKey}": {
          "reported": {
              "type": {paramType},
              "value": {paramValue},
              "timestamp": {timestampsValue}
          },
          "requested": {
              "type": {paramType},
              "value": {paramValue},
              "timestamp": {timestampsValue}
          },
          "syncStatus": {paramStatus}
      }
  }
  "notifyTo": ""
}

With:

paramKey

string uniquely identifying the device configuration parameter

paramType

indicates the config parameter type between: INT32, UINT32, BINARY, STRING or FLOAT,

paramValue

value requested for the parameter,

timestampsValue

update date of the parameter,

paramStatus

parameter update status; NONE, PENDING, SENT, OK or FAILED.

The section reported is present when the device has answered and corresponds to parameter configuration return by the device, the paramStatus could be OK or FAILED.

Error case:

HTTP Code Error code message

400

GENERIC_INVALID_PARAMETER_ERROR

The submitted parameter is invalid.

404

DM_DEVICE_NOT_FOUND

Device not found

Example:

{
    "parameters": {
        "MyParamFLOAT": {
            "requested": {
                "type": "FLOAT",
                "value": 1245,
                "timestamp": "2018-03-07T10:55:21Z"
            },
            "syncStatus": "PENDING"
        },
        "MyParamBINARY": {
            "requested": {
                "type": "BINARY",
                "value": "Nzg3ODY4Ng==",
                "timestamp": "2018-03-07T10:54:55.948Z"
            },
            "syncStatus": "SENT"
        },
        "MyParamINT32": {
            "reported": {
                "type": "INT32",
                "value": -333,
                "timestamp": "2018-03-07T10:53:21.934Z"
            },
            "requested": {
                "type": "INT32",
                "value": -333,
                "timestamp": "2018-03-07T10:53:21.937Z"
            },
            "syncStatus": "OK"
        }
    },
    "notifyTo": "fifo/configUpdateFifo"
}

8.2.5. Get state of a specific device configuration parameter

8.2.5.1. Request

Endpoint:

GET /api/v1/deviceMgt/devices/<deviceId>/config/parameters/<paramKey>

HTTP Headers:

X-API-Key: <your API key>
Content-Type: application/json
Accept: application/json

Example:

GET /api/v1/deviceMgt/devices/urn:lo:nsid:sensor:temp001/config/parameters/MyParamFLOAT
8.2.5.2. Response

HTTP Code:

200 OK

Body:

JSON Params Description

reported

Optional. reported configuration parameter value

requested

requested configuration parameter value

syncStatus

parameter update status; NONE, PENDING, SENT, CANCELED, OK or FAILED

Error case:

HTTP Code Error code message

400

GENERIC_INVALID_PARAMETER_ERROR

The submitted parameter is invalid.

404

DM_DEVICE_CONFIG_PARAM_NOT_FOUND

Device configuration parameter not found

Example:

{
    "requested": {
        "type": "FLOAT",
        "value": 1245,
        "timestamp": "2018-03-07T10:55:21Z"
    },
    "syncStatus": "PENDING"
}

8.3. Commands

This section describe how to set up command requests before sending them to the devices.

The Concepts and API described in this chapter allows to manage commands for MQTT, LoRa®, SMS and external connector interfaces.

8.3.1. Principle

A command request is a downlink message that Live Objects sends to the device, with acknowledgement mechanism. Depending on the interface (protocol & connectivity) used, a command response can be sent by the device to Live Objects.

You can register commands targeting a specific device: as soon as an interface for this device is available for commands, Live Objects will send them one by one, waiting for an acknowledgment for each command before sending the next one.

There is a limitation of 10 queued commands for a specific device.

Live Objects keeps a record of every registered command with its status, and possible response after processing by device.

The command control mechanism consists of two sub-mechanisms :

  • an application sub-mechanism that manages the displayed command statuses for the buisness applications and apply command cancel if need.

  • an additional sub-mechanism that manages the command delivery status to the device using the connectors.

8.3.2. Command status

The commands can have the following states:

Status Description

PENDING

The command is recorded and waiting for processing

RETRYING

The command has encountered an error, and will be retried. (same behaviour as PENDING)

PROCESSING

The command is being processed by the dedicated interface (waiting for an acknowledge)

PROCESSED

The command has reached its final acknowledgement level (FINAL STATE)

ERROR

An error occurred during the processing of the command (FINAL STATE)

CANCELED

The command was canceled before reaching PROCESSED state (FINAL STATE)

EXPIRED

The command could not be processed within the time limit (expirationTimeoutInSecond) (FINAL STATE)

Here is a status diagram with possible transitions:

Device commands states

Interactive

8.3.3. Command status summary table

Table 3. Here is the list of possible command statuses provided by each connectivity

Command Status \ Connector

LoRa®

MQTT

SMS

External Connector

PENDING

PROCESSING

PROCESSED

EXPIRED

CANCELED

RETRYING

ERROR

8.3.4. Delivery status

During the PROCESSING state, the device manager exposes an additional information: the delivery status. The delivery status provides more detailed information on the processing step of the command, based on the acknowledgement information available, depending on the connectivity used.

Device commands delivery states

Interactive

8.3.5. Acknowledgement level

The acknowledgement level determines the transition from the PROCESSING state to the PROCESSED state of a command.

The device manager offers three different levels of acknowledgement:

  • NONE : The device manager only listens to the internal acknowledgement that notifies the sending of the command. The command is output from Live Objects. Equivalent to the delivery status SENT

  • NETWORK : The device manager waits for protocol acknowledgment. Equivalent to the delivery status DELIVERED

  • APPLICATIVE : The device manager waits for an applicative acknowledgement, with potentially a response. Equivalent to the delivery status REPLIED

For each connector, the acknowledgement level implies a specific delivery status as described in MQTT acknowledge/status, LoRa® acknowledge/status, SMS acknowledge/status, External connector acknowledge/status.

8.3.6. Expiration Timeout

In most cases, the device availability cannot be accurately predicted, due to connectivity reason for example. In some cases, we need the command to be executed in a near future or not at all.

Let’s return to the example of our connected lock: when we send an "unlock" command, we want that the command will be executed within the next two minutes, not in three hours due to a connectivity issues.

The command API proposes the expiration timeout (default: 7 days, min: 5 seconds, max: 30 days). This is the maximal amount of time allowed to reach the status PROCESSING. If this value is exceeded, the status of the command goes to the status EXPIRED.

8.3.7. Acknowledgement Timeout

The command API proposes the acknowledgement timeout. This is the maximal amount of time allowed to reach the status PROCESSED when command is being processed (status PROCESSING). If this value is exceeded, the status of the command goes to the status ERROR with the error code ACK_TIMEOUT.

For each connector, the acknowledgement level implies a specific delivery status as described in MQTT ack timeout value, LoRa® ack timeout value, External connector ack timeout value.

A command with NONE acknowledgement cannot have acknowledgement timeout. For the other cases, an acknowledgement timeout is enforced.
Do not hesitate to customize this value. A value adjusted to your needs allows for better error detections, as well as a better reactivity of the command process

8.3.8. Attempts number

For some reasons (network issues, or acknowledgement default), a command can reach the acknowledgement timeout. In this case, we may have to retry sending command. This is the purpose of the attempts field in the command policy.

If another attempt can be made, instead of ERROR, the command status is set to RETRYING, equivalent to the PENDING status, but showing that it’s not the first attempt. Then, the command is treated normally.

If all attempts have been used, the command status is set to ERROR.

The default value of attempts is 1, which means there will be no retries. The maximum value is 5 (first attempt + 4 retries)