Device group
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. "IoT device and data 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"
}
Create a new group
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"
}
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"
}
Update a group
|
The path change of a group does not change its content (Devices, Groups). |
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"
}
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"
}
List groups
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 |
List Groups Query samples:
| QueryParams | Returned nodes |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
no result |
HTTP Headers:
X-API-Key: <your API key> Accept: application/json X-Total-Count: <boolean>
Example:
GET /api/v1/deviceMgt/groups?limit=20&offset=0
Response
HTTP Code:
200 OK
Body:
List of group object model
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"
}
]
Get a group
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
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"
}
Delete a group
|
You can’t delete a group which has devices. |
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
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 |
Device configuration
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.
-
(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".
-
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.
Get device configuration parameters
To retrieve the details of the configuration map of the device we can use the GET API.
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
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"
}
}
Set device configuration parameters
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 |
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"
}
}
}
Get a description of the device configuration
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
Response
HTTP Code:
200 OK
Body:
| JSON Params | Description |
|---|---|
parameters |
list of device configuration update |
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}
}
}
}
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"
}
}
}
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"
}
Commands
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.
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:
Command status summary table
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.
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.
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.
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 |
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) |
| If the command status is RETRYING and the expiration timeout is reached, the new attempts is abort, and the command status is set to EXPIRED (same behavior as PENDING). It is advisable to define an expiration timeout upper than (acknowldegement timeout x (attempts - 1)) |
Command object model
We will detail the command object model of the device manager, as used in API v1.
All possible operations on this object are detailed in the swagger.
Here is an unrealistic example, using a blank interface :
{
"id": "ae49129f-9ce4-4782-82c4c6a2",
"targetDeviceId": "urn:lo:nsid:sensor:2327398",
"request": {
"connector": "...",
"value": {
[...]
}
},
"response": {
[...]
},
"status": "PROCESSED",
"deliveryStatus": "REPLIED",
"errorCode": "INVALID_COMMAND_REQUEST",
"policy": {
"expirationInSeconds": 120,
"ackTimeoutInSeconds": 180,
"ackMode": "APPLICATIVE",
"attempts" : 1
},
"history": [
{
"timestamp": "2017-12-06T11:32:25.055Z",
"status" : "PENDING"
}, {
"timestamp": "2017-12-06T11:38:22.481Z",
"status": "PROCESSING",
"deliveryStatus": "SENT",
"errorCode": "INVALID_COMMAND_REQUEST",
"nodeId": "2327398"
}, {
"timestamp": "2017-12-06T11:38:24.124Z",
"status": "PROCESSED",
"deliveryStatus": "REPLIED",
"nodeId": "2327398",
}
],
"created": "2017-12-06T11:32:25.055Z",
"updated": "2017-12-06T11:38:24.124Z"
}
The root fields are as follows:
| JSON Params | Description |
|---|---|
id |
Unique id of the command |
targetDeviceId |
Targeted device identifier |
request |
Command request (Cf. command request format) |
response |
Optional. Command response from device |
status |
Status of the command. Please refer to Command status for more details. |
deliveryStatus |
Optional. Delivery status of the command. Please refer to Delivery status for more details. |
errorCode |
Optional. Error code encountered during command processing. |
policy |
Policy for the command (Cf. Policy format) |
history |
Contains the history of changes in the status of the command. (Cf. Command history) |
created |
Registration date of the command |
updated |
Last "status" update date of the command. |
The format of a command request is the following:
| JSON Params | Description |
|---|---|
connector |
connector/protocol to use to forward the command. Allowable values: mqtt, lora, sms or x-connector. |
value |
command value (protocol/connector-dependant) (Cf. MQTT value, LoRa® value, SMS value, External connector value) |
The format of the policy for a command is the following:
| JSON Params | Description |
|---|---|
expirationInSeconds |
Optional. expiration in seconds since command creation date. (Cf. Expiration Timeout). |
ackTimeoutInSeconds |
Optional. acknowledgement timeout in seconds since command is being processed. Default depends on connectiviy. Min value is 10 seconds (Cf. Acknowledgement Timeout). |
ackMode |
Optional. Ack mode for this command. Please refer to Acknowledgement level for more details. |
attempts |
Optional. Number of attempts in case of ERROR. Default to 1 Please refer to Attempts number for more details. |
The format of the history for a command is an array of this:
| JSON Params | Description |
|---|---|
timestamp |
Timestamp of this event |
status |
Status of the command at that moment |
deliveryStatus |
Optional. Delivery status of the command at that moment |
errorCode |
Optional. Error code encountered during command processing. |
nodeId |
Optional. NodeId of the interface used to process the command |
Command registering by connector
For each kind of connectivity, the command registering uses specific values, the final delivery status is also different according to acknowledgement level.
Case of MQTT
| To see how the commands are processed by device and to learn more, see the command section "device mode" |
Delivery status behaviour according to acknowledgement level
| Acknowledgment | NONE (just sent the command) | APPLICATIVE (waiting for response to validate) |
|---|---|---|
Description |
MQTT connector sent the command through open connection |
Applicative response from device (default value) |
Sequence of events & evolution of the statuses |
||
Final Success Delivery Status |
SENT |
REPLIED |
Default acknowledgement timeout |
- |
24h (7 days with v0 API), and the maximal value is 7 days. |
Values for command registration
Value field can be any valid JSON
| JSON Params | Description |
|---|---|
req |
the command in string format |
arg |
List of parameters.
Should not contain field name with |
Example: Let’s take the case of a command recorded for a device with an online MQTT interface, with an APPLICATIVE acknowledgement level.
{
"request": {
"connector": "mqtt",
"value": {
"req": "reboot",
"arg": {
"delay": 1000
}
}
},
"policy": {
"expirationInSeconds": 120,
"ackMode": "APPLICATIVE"
}
}
Please refer to the MQTT device mode part for messages that your device can send or receive.
| To see an example, go to MQTT Command Example section. |
Case of LoRa®
Delivery status behaviour according to acknowledgement level
| Acknowledgment | NONE (just sent the command) | NETWORK (waiting for network/protocol ack) |
|---|---|---|
Description |
Downlink report received (default value) |
Downlink acknowledge received |
Sequence of events & evolution of the statuses |
||
Final Success Delivery Status |
SENT |
DELIVERED |
Default acknowledgement timeout |
- |
For LoRa®, the acknowledgement rely on a double mechanism: - first correlated with the device traffic: the LoRa® connector waits maximum 3 uplinks to get an ACK bit set to 1. Beyond 3 uplinks without ACK bit acknowledgement timeout is reached. - second is acknowledgement timeout delay: default: 7 days, max is 7 days. |
Values for command registration
Value field in request command sets the following parameters:
| JSON Params | Description |
|---|---|
data |
hexadecimal raw data of the command |
port |
port of the device on which the command will be sent (1 to 254) |
Example:
{
"request": {
"connector":"lora",
"value":{
"data": "A1FF20",
"port": 1
}
},
"policy": {
"expirationInSeconds" : 200,
"ackMode": "NONE"
}
}
| To see an example, go to LoRa® Command Example section. |
Case of SMS
Delivery status behaviour according to acknowledgement level
| Acknowledgment | NONE (just sent the command) |
|---|---|
Description |
Message sent (default value) |
Values for command registration
Value field in request command sets the following data:
| JSON Params | Description |
|---|---|
payload |
message to send TEXT : size max 160 characters and GSM 7 compatible characters (for more information, see GSM 03.38 standard or chapter 6.2.1 of https://www.etsi.org/deliver/etsi_gts/03/0338/05.00.00_60/gsmts_0338v050000p.pdf) BINARY : size max 260 characters (140 octets) and hexadecimal characters |
serverPhoneNumber |
server phone number. Must be defined in the offer settings |
type |
message format in TEXT or BINARY |
Example:
{
"request": {
"connector": "sms",
"value": {
"payload": "Hello Live Objects!",
"type": "TEXT",
"serverPhoneNumber": "20406"
}
},
"policy": {
"expirationInSeconds" : 30,
"ackMode": "NONE"
}
}
| To see an example, go to SMS Command Example section. |
Case of External connector
Delivery status behaviour according to acknowledgement level
| Acknowledge required | NONE (just sent the command) | APPLICATIVE (waiting for response to validate) |
|---|---|---|
Description |
External connector sent the command through open connection |
Applicative response from device (default value) |
Sequence of events & evolution of the statuses |
||
Final Success Delivery Status |
SENT |
REPLIED |
Default acknowledgement timeout |
- |
For External connector, the default value of acknowledgement timeout is 24h, and the maximal value is 7 days. Beyond that, the acknowledgement timeout is reached |
Values for command registration
Value field in request command can be any valid JSON. It can contain a map of 100 entries maximum. Each entry can contain 255 characters maximum.
Example: Let’s take the case of a command recorded for a device with an online external connector interface, with an APPLICATIVE acknowledgement level.
{
"request": {
"connector": "x-connector",
"value": {
"myCommand": "turn on",
"myParams": {
"device": "6"
}
}
},
"policy": {
"expirationInSeconds": 60,
"ackMode": "APPLICATIVE"
}
}
Command examples by connector
Example for Mqtt
Let’s take the example of a smart lock, connected to Live Objects with an MQTT interface.
Description
From your smartphone, you want to unlock your door for a family member who forgot his keys. The application on your phone will create a command on Live Objects, who will send it to the door
-
You want to know if your unlock request has been well executed.
-
You need to set the maximum waiting time for your order to be executed : 2 minutes here, not three hours due to a connectivity issues.
To do this, you must :
-
Have smartphone business application connected to LO.
-
A smart lock system online who subscribe to the topic dev/cmd on Live Objects
-
Your device must support command capability (check the device before beginning).
Then apply this steps :
-
Send a command request.
-
Wait the processing time
-
Check the result from your smartphone.
Command request details
Your smartphone have to send the following request to LO :
API : POST /api/v1/deviceMgt/devices/<deviceId>/commands
Request sample :
{
"request": {
"connector": "mqtt",
"value": {
"req": "unlock",
"arg": {
"delay": 1000
}
}
},
"policy": {
"expirationInSeconds": 120, (1)
"ackMode": "APPLICATIVE" (2)
"ackTimeoutInSeconds": 180, (3)
}
}
| 1 | When you register a command you must set the expiration timeout, to fix a limit delay for PENDING/RETRYING status, this means that once the command has been registred, Live Objects will wait for a device subscription to the corresponding topic under this delay. Once this delay exceeded without new event from the device, the command status change automatically to EXPIRED. |
| 2 | Depending on the Acknowledgement level you have set, Live Objects will wait for a response from the smart lock. |
| 3 | If you have set the ackMode to applicative, you can also override the acknowledgement timeout to limit the maximum response time allowed to the device. In this case, we choose an APPLICATIVE acknowldegment level, so a response from the device is mandatory. |
Timeouts during the process
Check the status of the command
API : GET /api/v1/deviceMgt/commands/{commandId}/status
Response :
{
"content": "PROCESSED"
}
Response for the entire command, the request is the same but use another endpoint
API : GET /api/v1/deviceMgt/commands/<commandId>
Response :
{
"id": "ae49129f-9ce4-4782-82c4c6a2",
"targetDeviceId": "urn:lo:nsid:smartlock:123456",
"request": {
"connector": "mqtt",
"value": {
"req": "unlock",
"arg": {
"delay": 1000
}
}
},
"response": {
"done": true
},
"status": "PROCESSED",
"deliveryStatus": "REPLIED",
"policy": {
"expirationInSeconds": 120,
"ackTimeoutInSeconds": 180,
"ackMode": "APPLICATIVE"
},
"history": [
{
"timestamp": "2017-12-06T11:32:25.055Z",
"status" : "PENDING"
}, {
"timestamp": "2017-12-06T11:38:22.481Z",
"status": "PROCESSING",
"deliveryStatus": "SENT",
"nodeId": "abcd123456"
}, {
"timestamp": "2017-12-06T11:38:24.124Z",
"status": "PROCESSED",
"deliveryStatus": "REPLIED",
"nodeId": "abcd123456"
}
],
"created": "2017-12-06T11:32:25.055Z",
"updated": "2017-12-06T11:38:24.124Z"
}
Example for LoRa®
Let’s take the example of a smart sensor of water metering, connected to Live Objects with LoRa® interface.
Description
The objective is to monitor a water usage monthly. To do this, you must :
-
Send a "reset to zero" command to the water meter at the end of the month.
-
The command will be sent in a binary format supported by LoRa® connectivity.
-
-
Have water meter system connected to Live Objects with LoRa® interface.
Then apply this steps :
-
Register command through Live Objects portal or your business application.
-
Follow the command status during the operation.
-
Check the result
| The LoRa® devices has a low energy consumption as well as sleeping time is relatively long. So, the command request takes time to be processed. The expiration timeout must be set with high values. |
Command processing policy
-Set your command processing policy before registering_
POST /api/v1/deviceMgt/devices/urn:lo:nsid:lora:watermeter123/commands
{
"request": {
"connector": "lora",
"value": {
"data": "44D2F0",
"port": "125"
}
},
"policy": {
"expirationInSeconds": 28800, (1)
"ackMode": "NETWORK" (2)
}
}
| 1 | The expiration timeout can be setted to replace the default limit delay for PENDING/RETRYING status. |
| 2 | Depending on the Acknowledgement level setted, Live Objects will wait for a response from the water meter. In this case, we choose a NETWORK acknowldegment level, so a response from the LoRa® network is mandatory. |
The acknowledgment timeout can’t be setted by the customer
Example for SMS
We return to the example presented previously of a smart lock with the MQTT interface, in this example we have connected our Unlock system to Live Objects with an SMS interface.
Now we register a command through an SMS interface and Live objects will be sent this command with an SMS message to connected device.
Register command
POST /api/v1/deviceMgt/devices/urn:lo:nsid:sms:unlock123/commands
{
"request": {
"connector": "sms",
"value": {
"payload": "unlock",
"type": "TEXT"
}
},
"policy": {
"expirationInSeconds": 60, (1)
"ackMode": "NONE" (2)
}
}
| 1 | When you register a command you must set the expiration timeout, to fix a limit delay for PENDING/RETRYING status, this means that once the command has been registred, Live Objects will wait until the request was sent. Once this delay exceeded, the command status change automatically to EXPIRED. (This can happen if you have paused your SMS interface for exemple) In this case, after 60 seconds waiting, Live Objects change the status of the command at EXPIRED. |
| 2 | When your device use SMS interface, only ackMode NONE is supported. |
Register a binary command
The same example with a binary command
POST /api/v1/deviceMgt/devices/urn:lo:nsid:sms:unlock123/commands
{
"request": {
"connector": "sms",
"value": {
"payload": "756e6c6f636b", (1)
"type": "BINARY" (2)
}
},
"policy": {
"expirationInSeconds": 60,
"ackMode": "NONE"
}
}
| 1 | Payload in hex format, converted from string = "unlock". |
| 2 | Payload type must be set with value = BINARY |
Device resources
Principle
LiveObjects offers a resource feature that allow customers to follow devices reported resources, manage new resource versions, and update device resource with fresh version.
The main goal is to provide resource update facility, where the update principle is :
-
The Device connects and exchanges with LiveObjects.
-
The Customers defines some resources for his tenant,
-
The Customers asks LiveObjects to update device resource versions for some devices.
-
The Device communicate with LiveObjects to process the update.
-
LiveObjects reports to the Customer the current state of updates and device resources.
Manage and follow resource update
LiveObjects provides to the Customer DM resource related API in order to:
Manage resource inventory for his tenant :
-
add, update, remove
resource versions,
Manage device resources :
-
get device resources
reported versions, -
set, or reset device resources
requested versions,
Follow and manage update operations :
-
createdevice resource update operation. -
cancelan update. -
get, or list device
updates states,
Here is an example of Customers in-sequence actions :
-
create a new resource version for his tenant,
-
async trigger an update by setting a requested versions for a given device,
-
get latest device update to track update operation state.
Resource versions management
A resource is a versioned binary content (for example a device firmware). You can manage a repository of resources in your tenant account.
For each resource you can manage multiple resource versions.
Live Objects can track the current versions of resources on a specific device.
Customers can plan an update by setting a requested version for a given device resource version, or can order immediately an update.
| Device resource requested versions | Device resource versions updated |
|---|---|
Optional compatibility restrictions can be configured between versions to avoid compatibility issues when switching from a version to another.
Live Objects will refuse a resource update request that don’t match the compatibility restrictions.
Different kind of updates
As today, Live Objects supports two kind of updates:
-
a resource update that rely on
http-updaterupdater (with mqtt and Lwm2m devices):
LiveObjects provides the resource in the form of a secure (https) or insecure (http) URL. Then the Device will decide when to act as http client and query that URL to retrieve the content.
-
a resource update that rely on
lwm2m-updaterupdater with Lwm2m devices (Beta):
LiveObjects rely on Twin to send LwM2M operations, and will send the resource to the Device via downlink operation (ex. Twin write).
Here is a summary of resource updates mode compatibility and feature matrix
| Updater | Connectivity | Update trigger |
|---|---|---|
http-updater |
MQTT |
set requested version |
create update |
||
http-updater |
LwM2M |
create update |
lwm2m-updater |
LwM2M |
create update |
Resources inventory
Resources and versions definitions
Customer defines for his tenant a set of resources.
A resource is:
-
a
resourceId: a unique identifier (ex.X113DevFirmware, EPROM7300_V12). -
a
label(optional) -
a
description(optional) -
a
connector(optional): the default related updater -
some
meta-data -
some
aliases(optional)
For each resource, Customer then defines one or more resource versions.
A resource version is:
-
a given unique version identifier (ex.
1.0,1.1a), -
a file content,
-
a checksum of the file content,
-
an optional list of the compatible versions from which you can update to this firmware.
Resources aliases
You can configure zero, one or several aliases on a resource to help you manage your resource update operations.
An alias can be used to replace with a string of your choice a resource version when requesting a new target for a resource.
For example you could create an alias preprod to refer or target the 1.1a resource version.
You can use up to 5 aliases per resource.
A same version can be used in several aliases. An alias key must be unique.
Resources versions compatibility
When a resource version includes at least one or more compatible versions,
LiveObjects must check that the current device resource reported version is compatible in order
to target an update to this resource version.
When a resource version compatible versions is empty or missing,
LiveObjects is able to target an update to this resource version without version check.
For example, if 1.1a compatible versions are [0.8, 1.0, 1.1], then
-
a device which reports
0.8as current version is compatible -
whereas a device which didn’t report current version, or which reports
0.9(or1.2) version is NOT compatible and cant be updated to1.1a.
Resource definition API examples
Create a new resource
POST /api/v0/rm/X113DevFirmware
{
"connector": "http-updater",
"resourceId": "X113DevFirmware",
"label": "X113 DEV",
"description": "X113 firmware of box, in DEV mode.",
"metadata": {
"BoxSeriesSuffix": "FF1Fxx42"
}
}
Response
{
"tenantId": "5ae04ef29a92790fd7f2a5e4",
"resourceId": "X113DevFirmware",
"label": "X113 DEV",
"description": "X113 firmware of box, in DEV mode.",
"connector": "http-updater",
"metadata": {
"BoxSeriesSuffix": "FF1Fxx42"
},
"creationTs": 1677496010873,
"updateTs": 1677496010873
}
Remove a given resource
DELETE /api/v0/rm/X113DevFirmware
Create a new resource version
POST /api/v0/rm/X113DevFirmware/version
{
"file": "iVBORw0KGgoAAAANSUh...UVORK5CYII=",
"checksum": "9WeAuNlX/WaappCx4sSMYQ==",
"resourceVersionId": "1.0",
"compatibleVersions": ["0.5","0.8","0.9"]
}
This sample adds a new X113DevFirmware firmware resource version 1.0.
This version is compatible with following versions: 0.5, 0.8, 0.9.
-
fileattribute is base64 encoded file content (abbreviates in the example above). -
checksumismd5of the raw firmware content encoded in base64.
Example of generating md5 checksum :
import com.google.common.hash.Hashing;
import com.google.common.io.BaseEncoding;
import java.io.File;
import java.nio.file.Files;
import org.apache.commons.io.FileUtils;
import org.junit.Test;
// ...
File file = new File("C:/tmp/myFirmware.bin");
byte[] fileBytes = FileUtils.readFileToByteArray(file);
String fileB64 = BaseEncoding.base64().encode(fileBytes);
byte[] fileMd5Sum = Hashing.md5().hashBytes(fileBytes).asBytes();
String fileB64OfMd5Sum = BaseEncoding.base64().encode(fileMd5Sum);
System.out.println("::fileB64> " + fileB64);
System.out.println("::checksum> " + fileB64OfMd5Sum);
Remove a given resource version
DELETE /api/v0/rm/X113DevFirmware/version/1.0
This sample removes X113DevFirmware firmware resource version 1.0.
Version management
Device declaration
Depend of the protocol, the device could report the current version of his resources.
This device initiated declaration is mandatory when relying on resources with compatibility restrictions.
But LiveObjects is also able to execute update operation without device declaration when relying on resources with NO compatibility restrictions.
-
For MQTT, please refer to Current Resources publication section.
-
For LwM2M, as today there is no device declaration, and so update must rely on resources without compatibility restrictions.
Version operation
Set or Reset requested version
Customer can set requested versions on devices :
In order to plan an update, Customer can record some intention : set a requested versions on one or more device resources.
This way represent an asynchronous trigger of the update operation because the update operation is created at LiveObjects initiative: when we know that the device is compatible, and when the device is ready to accept a new update (cf. conditions bellow).
Customer can reset requested versions on devices :
To remove any update intention, the reset operation will clean the requested version.
In that case, there is a chance that the update were already created/started : in that case LiveObjects will cancel related update too.
|
Note that |
Create an update
Customer can create an update operation on devices :
In order to immediately trigger an update, LiveObjects let you create a device update directly. This way represent a synchrone trigger of the update operation: the update operation is started at Customer initiative.
This operation may be immediately rejected in some case:
-
we already know that the device is not compatible,
-
an update is already in progress on that device.
When the device is not ready, or when we don’t know if he is compatible, then the update will stay in his initial state(PENDING), and will progress later.
|
Note that |
Update trigger
Here is a summary of updates conditions
| Connectivity | Updater | Update conditions |
|---|---|---|
MQTT |
http-updater |
Mqtt connection is established, the device is listening resource update requests, and the compatibility restrictions (if any) are fulfilled. |
LwM2M |
lwm2m-updater |
LwM2M device is connected, the device supports and instantiate the first Firmware Object ( - firmware update state ( - in-band delivery with lwm2m-updater : device must support push delivery method ( - out-of-band delivery with http-updater : device must support pull delivery method ( |
http-updater |
Version management API examples
Set device resource requested version
Request
POST /api/v1/deviceMgt/devices/urn:lo:nsid:sensor:temp001/resources/MyResource001
{
"version": "1.1",
"metadata" : {
"secured" : true
}
}
Response
{
"reported": {
"version": "1.0",
"timestamp": "2020-03-12T10:43:18.350Z"
},
"requested": {
"version": "1.1",
"timestamp": "2020-07-23T14:53:03.959Z"
}
}
| JSON Params | Description |
|---|---|
reported |
current device resource status |
requested |
requested resource status |
version |
resource version |
timestamp |
date of resource version association |
metadata |
metadata associated with this device (if any) |
Set device resource version using alias
Configure an alias
Request
PUT /api/v0/rm/MyResource001
{
"connector": "http-updater",
"metadata": {
"secured": true
},
"versionAliases" : {
"prod" : "1.1",
"preprod" : "1.2"
}
}
Response
{
"resourceId" : "MyResource001",
"connector" : "http-updater",
"metadata" : {
"secured" : "true"
},
"versionAliases" : {
"prod" : "1.1",
"preprod" : "1.2"
},
"creationTs" : 1563191282476,
"updateTs" : 1595594676082
}
Set requested version alias
Request
POST /api/v1/deviceMgt/devices/urn:lo:nsid:sensor:temp001/resources/MyResource001
{
"version": "prod",
"metadata" : {
"secured" : true
}
}
Response
{
"reported": {
"version": "1.0",
"timestamp": "2020-03-12T10:43:18.350Z"
},
"requested": {
"version": "1.1",
"timestamp": "2020-07-23T14:53:03.959Z"
}
}
|
The requested alias must exist and meet the compatibility restrictions |
Reset device resource version
Request
DELETE /api/v1/deviceMgt/devices/urn:lo:nsid:sensor:temp001/resources/MyResource001/requested
This DELETE call will remove the requested version of the device resource MyResource001 if related update has not been triggered.
If an update already exists for this device resource, then requested version is untouched. If the update is active, internally, a soft cancel is done.
Create resource update
Request
POST /api/v1/deviceMgt/devices/urn:lo:nsid:sensor:temp001/resources/MyResource001/updates
{
"requestedVersion": "1.0",
"connector": "http-updater",
"metadata": {
"secured": true
}
}
Response
{
"id": "5f3bf1ecb23f3277805478a7",
"resourceId": "MyResource001",
"created": "2023-03-02T15:21:16.128Z",
"updated": "2023-03-02T15:21:16.128Z",
"initialVersion": "0.8",
"requestedVersion": "1.0",
"connector": "http-updater",
"status": "PENDING",
"metadata": {
"secured": true
}
}
| JSON Params | Description |
|---|---|
resourceId |
device resource to update |
created |
resource update creation date |
updated |
resource update update date |
initialVersion |
device resource initial version |
requestedVersion |
device resource requested version |
connector |
updaterConnector to use. Can be If not provided, the If the resource has no associated |
metadata |
metadata associated to this update |
Update Operation
Update states
Customer can get, or list resource updates.
This is different states values for a resource update :
| State | Description |
|---|---|
PENDING |
This is update operation initial state. The device is not yet ready or didn’t report his current version. |
PREPARING_CONNECTOR |
The update operation is now in progress and related update connector is initializing (internal). |
PREPARING_ASSET |
verify the device state or ask to the device to accept update. |
WAITING_TRANSFER_INFO |
waiting the device to accept the update |
TRANSFER_PENDING |
resource transfer is ready to start |
TRANSFER_IN_PROGRESS |
resource transfer is in progress |
TRANSFER_SUCCESS |
resource transfer is just done with success |
CANCELED |
The update operation has been canceled. This is a final state. |
ERROR |
The update operation has failed. This is a final state. |
DONE |
The update operation is done successfully. This is a final state. |
Update timeouts
An active update has 2 timeout windows:
-
after the resource update request (LiveObjects → Device request with
http-updaterupdate). -
for the overall update (for
http-updater, andlwm2m-updaterupdates).
After the resource update request:
-
the device does not confirm the resource update request and does not download or report the version. After
5 minutes, the update returns to thePENDINGstate. -
the device accepts the resource update request but does not download or report the version. After
5 minutes, the update will end with a timeout error (ERRORstate).
For the overall update
-
an active update (update with a state not in
DONE,CANCELED,ERROR) MUST NOT be older than24 hours. After 24 hours, the update will end with a timeout error (ERRORstate).
Cancel an update
There is multiple ways to cancel an update :
-
reset device resource requested version to cancel a set requested version,
-
soft cancel a resource update.
-
hard (aka. force) cancel a resource update.
The "reset" method will clean an expected requested version. If the update has already been triggered and is always active, a soft cancel is internally done.
The "soft" cancel update method will interrupt an active update in the following state : PENDING, PREPARING_CONNECTOR.
The "hard" cancel update method will interrupt an active update in the following state : PENDING, PREPARING_CONNECTOR, PREPARING_ASSET,WAITING_TRANSFER_INFO, TRANSFER_PENDING, TRANSFER_IN_PROGRESS, TRANSFER_SUCCESS.
Updaters
In order to send the binary content to a device, Live Objects is built to provide different type of transfert protocols.
Those protocols are handled by updaters.
Updaters can support configuration parameters called metadata.
-
Http-updater
Live Objects provides a http-updater updater that allows the device to download the resource using HTTP protocol. http-updater is available with devices that have MQTT or Lwm2m (through "out-of-band" mode)
http-updater supports the following metadata:
| Meta-data | Description |
|---|---|
|
To enable https link for resources update, the default value is set to false (i.e. http link). It’s possible to set this "secured" metadata from device resource metadata, resource metadata, or update operation metadata. |
-
Lwm2m-updater
Live Objects provides a lwm2m-updater updater that relies on LWM2M Specifications to process an update.
As today lwm2m-updater supports the push mode and rely on "Firmware(5)" object to read device firmware status, write, then execute firmware package and read firmware update result.
lwm2m-updater has no specific metadata.
Resource update process
Resource update with MQTT connector and HTTP updater
Live Objects will prepare the resource on public available endpoint and send update information to the device.
The device is responsible to download the resource, and then report his state to LiveObjects .
Trigger
How to trigger a resource update:
-
You can
set the requested versionof resources for a specific device in Live Objects that will then try to update the resources on the device as soon as the device is available for resource update. -
You can trigger by
creating an updatedirectly.
step 1 - Resource update context
-
the customer defines some resources, and some resource versions with, or without compatibility constraints on Live Objects : cf resources definitions.
-
the device reports its current resources and versions.
-
the customer may set and reset requested versions on some device resources on Live Objects. cf. device resource set example, and device resource reset example.
|
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. There is some practical examples in Resources update section like Current Resources publication. |
step 2 - New update
-
customer creates an update directly via API. cf. create resource update example.
-
or Live Objects automatically triggers an update for not honored requested resource versions set.
Pre-requisites: a new update is activated when
-
the device is ready to receive resource update (resource capability is available),
-
there is no update in progress.
When there is compatibility restrictions, then the device resource current version MUST be known.
step 3 - Prepare connector
-
Live Objects prepares the resource version binary and generates a download link.
step 4 - Prepare asset
-
Live Objects sends the download link and resource version id to the device
-
optional the device can respond to indicate whether it accepts the new resource version or not.
-
optional the device can send a customized error. The operation will be stated as failed
step 5 - Transfer
-
the device can download the binary.
-
optional at anytime, the operation can be cancelled. In this case Live Objects will remove the download link. cf. the section dedicated to cancellation.
-
when the device does not start the download, then timeout can occur cf. section dedicated to timeout.
-
when the device has not responded to the request and does not start the download, the update returns to the PENDING state.
step 6 - Final
-
download is done
-
the device can check the file integrity using the provided md5, and perform internal updates.
-
to acknowledge the binary reception and the update, the device sends a new current resources message.
-
Live Objects compares the current and expected resource version and updates the operation status accordingly.
http-updater resource update states
Resource update with Lwm2m connector - (Beta)
|
APIs allow to manage lwm2m-updater resource update only for LWM2M connector. |
Live Objects will prepare te resource and send it to the device with a downlink operation.
The device MUST be compliant with related standard to accept the resource, and report his state to LiveObjects.
Trigger
How to trigger a resource update with lwM2M connector :
-
You can trigger by
creating an updatedirectly.
step 1 - Resource update context
-
the customer defines some resources, and some resource versions.
As today, you must use resource without compatibility restrictions.
step 2 - New update
-
customer creates an update directly via API. cf. create resource update example.
-
customer selects the connector :
"lwm2m-updater"forpushupdate or"http-updater"forpullupdate.
Pre-requisites: a new update is activated when
-
the device is ready to receive resource update (resource capability is available) : Lw device is connected and instantiate object
/5/0, -
there is no update in progress.
-
the device supports selected delivery method and http(s) protocol if
"out-of-band"update is selected.
step 3 - Prepare resource
-
LiveObjects internally prepares the requested resource version content to send.
step 4 - Prepare device: await device initial state
-
LiveObjects will use Twin operations to ask to the device the first Firmware instance (
/5/0).
This provides some relevant informations : state (/5/0/3), protocol support(/5/0/8), delivery method(/5/0/9).
In order to start a firmware update sequence, following conditions apply :
-
the device state MUST be
0:IDLE. -
(when using http-updater) protocol support and delivery method MUST be compatible with underlying update.
-
On unexpected read/state issue, the read operation is retried with a retry backoff mechanism. Note that on unexpected compatibility there is no retry, the update is directly moved to
ERROR. -
On unexpected read/state issue and max retry attempts reached, the update is moved to
ERROR. -
On satisfying conditions, device update will go to the next step : transfer.
option - Interruption
During an update in progress, some interruptions can occur:
-
Customer can ask to cancel the update: on cancel, the update is moved to
CANCELED. cf. the section dedicated to cancellation. -
LiveObjects can detect that the update reached global update timeout: on timeout, the update is moved to
ERROR. cf. section dedicated to timeout.
NOTE: once the update request (step 4 - prepare device) has been sent, the cancel or timeout interruption impacts only on the update state. Customer can order a new update that will overwrite current residual update operation and restart a fresh update from scratch.
step 5 - Transfer operation
In case of push update (in-band write)
-
Live Objects sends the firmware package to the device with Lwm2m write operation.
-
Live Objects will rely on Twin WRITE operation to push the content of the resource to the device.
In case of pull update (out-of-band)
-
Live Objects has created a HTTP(s) download link and provides this URI to the device.
-
Device downloads the package content from this URI.
step 6 - Transfer verify result
-
resource is moving on device side
-
the device is responsible to update his internal state (ex. from
1:DOWNLOADINGto2:DOWNLOADED) -
Live Objects will rely on Twin READ operation to get back
Firmware state(/5/0/3) andFirmware update result state(/5/0/5). -
Live Objects expects state to be
2:DOWNLOADEDand result state to be0:INITIAL. -
Live Objects reads state retries in the limit of
max retries: cf. DM Resource limitations -
on success, the transfer is considered as a success and the update moves to the next step,
-
on read issue or unexpected states after max retries, the update moves to
ERRORstate.
step 7 - Execute firmware update
-
Live Objects will rely on Twin EXECUTE operation
Firmware update execute(/5/0/2). -
resource is already on device side
-
the device can perform internal operations, updates, reboot, etc.
-
to acknowledge the binary reception and the update operation, the device is responsible to update his internal Firmware update result state.
step 7 - Await device update result state
-
update is in progress, then done on device side
-
the device is responsible to update his internal
Firmware update result state(/5/0/5) to1:UPDATED_SUCCESSFULLY -
Live Objects will rely on Twin READ operation to get back
Firmware update result state(/5/0/5). -
Live Objects expects state to be
1:UPDATED_SUCCESSFULLY. -
Live Objects reads update result retries in the limit of
max retries: cf. DM Resource limitations -
on success, the overall update is considered as a success and the update is
DONE. -
on read issue or unexpected states after max retries, the update moves to
ERRORstate.
lwm2m-updater resource update states
Creation
When creating a campaign, the user must provide the following information:
- name
-
A short name to identify the campaign
- description
-
(optional) Detailed description of the campaign
- options
-
(optional) Set of campaign options.
- planning
-
The scheduling configuration including the start date and the end date for the campaign
- targets
-
Devices targeted: either
idListorfilterQuery(exclusively). cf. Campaign targets - operations
-
A sequence of operations that will be executed on each device of the campaign.
Campaigns are created from the REST API by providing a campaign definition with properties described previously.
| Campaigns management are available for all types of devices (MQTT, LoRa®, SMS, LwM2M and External connector), for all connectivity, however you must take into consideration the capabilities and the conformity of the configurations, commands and resource that you push in your campaigns. Make sure that the devices support the requests that you send through connectors and through the networks. For normal use, only one connectivity is targeted by the filters or by the list of device id’s. |
Options
Campaign options section could be empty or omitted.
Example of campaign options:
"options": {
"dynamicallyAddEligibleDevice": true
}
Options are:
-
dynamicallyAddEligibleDevice(default:false).-
Set this option to
trueto dynamically enroll devices to the campaign. During the campaign planning, new or updated devices could be dynamically enrolled if they match thefilterQuery. -
This option requires a
filterQuerytarget definition. -
A campaign with
dynamicallyAddEligibleDeviceoption will always be inrunningstate until end date,
-
whereas others (non-dynamics) campaigns could end as soon as all devices operations ended or end date reached.
Operations
A campaign includes one or more operations:
-
Operation type is directly related to device capabilities.
-
Operation types are Config, Command, Resource, Twin operations, Twin observations
For each device, operations are executed one after the other, each operation waits for the success of the previous operation.
All operations definitions (except TWIN operations) could embed an optional maxRetry attribute:
-
default is
0, and max is5. -
In case of operation failure, operation will be retried in the limit of
maxRetry.
If an operation fails after maxRetry attempts (or is canceled) for a device, the remaining operations are not executed for this device and the sequence ends in failure (or in canceled status).
Config operation
Example of config operation definition:
{
"action":"configure",
"definition":{
"assetParameters":{
"param1":{
"type":"INT32",
"valueInt32":1234
}
},
"maxRetry": 1
}
}
- action
-
-
configureaction will send to the device one or many "parameters" to update.
-
- definition
-
-
assetParametershas the same format as the corresponding unitary device management operation: Device configuration. -
maxRetry(optional) defines how many retries should be executed in case of failure of the current operation.
-
The following table shows how the config operation statuses are converted into sequence statuses
Config operation status |
Resulting status in the sequence |
PENDING |
if it is the first operation: PENDING, if not: IN_PROGRESS |
SENT |
IN_PROGRESS |
CANCELED |
CANCELED |
OK |
if it is the last operation: SUCCESS, if not: PENDING and the sequence moves onto the next operation |
FAILED |
FAILURE |
Command operation
Example of command version 1 operation definition:
{
"action":"command",
"version":1,
"definition":{
"request": {
"connector": "mqtt",
"value": {
"req": "rebootV1",
"arg": {
"delay": 1000
}
}
},
"policy": {
"expirationInSeconds": 120,
"ackMode": "APPLICATIVE"
},
"maxRetry": 0
}
}
- action
-
-
commandaction will register (and send) a command to the device.
-
- definition
-
-
this section uses the same format as the corresponding unitary device management operation: Commands.
-
maxRetry(optional) defines how many retries should be executed in case of failure of the current operation.
-
The following table shows how the command operation statuses are converted into sequence statuses
Command operation status |
Resulting status in the sequence |
PENDING |
if it is the first operation: PENDING, if not: IN_PROGRESS |
PROCESSING |
IN_PROGRESS |
PROCESSED |
if it is the last operation: SUCCESS, if not: PENDING and the sequence moves onto the next operation |
CANCELED |
CANCELED |
ERROR |
FAILURE |
EXPIRED |
FAILURE |
UNKNOWN |
FAILURE |
Resource update operations
Campaign supports both resource update operations:
Resource operation setting a target version
Example of resource operation definition:
{
"action": "resource",
"definition": {
"resourceId": "X11_firmware",
"targetVersion": "2.1",
"maxRetry": 4,
"metadata" : {
"secured" : true
}
}
}
- action
-
-
resourceaction will set a device resource requested version (an update request is sent to the device when the device become capable).
-
- definition
-
-
resourceIdidentifies the resource to update. -
targetVersionis the new version of the resource to download and install. Aliases can also be used but the resolution of the version will be made for each operations when sent to the Device Manager. In other words, modifications on an alias that is used in a running campaign can affect the target version of the campaign. -
maxRetry(optional) defines how many retries should be executed in case of failure of the current operation. -
metadata(optional) is the metadata associated with this resource update request.
-
Resource operation creating an update
Example of resource-update operation definition:
{
"action":"resource-update",
"definition": {
"resourceId": "F500 Dev FirmwareLWM2M",
"requestedVersion": "v2",
"connector": "lwm2m-updater",
"maxRetry": 4,
"metadata" : {
"color" : "blue"
}
}
}
- action
-
-
resource-updateaction will create a resource update of to the device.
-
- definition
-
-
resourceIdidentifies the resource to update. -
requestedVersionis the new version of the resource to download and install. -
connector(optional) is the Updater to use for the resource update. When not set, the resource related updater is used, else the default updater is used. -
maxRetry(optional) defines how many retries should be executed in case of failure of the current operation. -
metadata(optional) is the metadata associated with this resource update request.
-
Resource operations statuses
The following table shows how the resource operation statuses are converted into sequence statuses
Resource operation status |
Resulting status in the sequence |
PENDING |
if it is the first operation: PENDING, if not: IN_PROGRESS |
PREPARING_CONNECTOR |
if it is the first operation: PENDING, if not: IN_PROGRESS |
PREPARING_ASSET |
IN_PROGRESS |
WAITING_TRANSFER_INFO |
IN_PROGRESS |
TRANSFER_PENDING |
IN_PROGRESS |
TRANSFER_IN_PROGRESS |
IN_PROGRESS |
TRANSFER_SUCCESS |
IN_PROGRESS |
DONE |
if it is the last operation: SUCCESS, if not: PENDING and the sequence moves onto the next operation |
ERROR |
FAILURE |
CANCELED |
CANCELED |
LwM2M Twin operations
Campaign supports all Twin operations.
LwM2M Twin READ operation
Example of twin read operation definition:
{
"action": "twin-operation",
"definition": {
"type": "READ",
"paths": [
"/5"
],
"policy": {"attempts" : 2}
}
}
- action
-
-
twin-operationaction will send a TWIN operation request to the device.
-
- definition
-
-
typeREAD : order the device to report some attributes. -
pathsTarget paths of related device objects or attributes. -
policy.attempts(optional) defines the maximal number of attempts until the operation is successfully completed
-
LwM2M Twin EXECUTE operation
Example of twin execute operation definition:
{
"action": "twin-operation",
"definition": {
"type": "EXECUTE",
"paths": [
"/1/0/8"
],
"policy": {"attempts" : 1}
}
}
- action
-
-
twin-operationaction will send a TWIN operation request to the device.
-
- definition
-
-
typeEXECUTE : execute some attributes. -
pathsTarget paths of related device objects or attributes. -
policy.attempts(optional) defines the maximal number of attempts until the operation is successfully completed
-
LwM2M Twin WRITE operation
Example of twin write operation definition:
{
"action": "twin-operation",
"definition": {
"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"
}
],
"policy": {"attempts" : 3}
}
}
- action
-
-
twin-operationaction will send a TWIN operation request to the device.
-
- definition
-
-
typeWRITE : update or replace some object attributes values. -
pathsTarget paths of related device objects or attributes. -
optionsOptions of Twin Operation, cf. Operation options section. -
valuesValues to set. -
policy.attempts(optional) defines the maximal number of attempts until the operation is successfully completed
-
LwM2M Twin WRITE METADATA operation
Example of twin write metadata operation definition:
{
"action": "twin-operation",
"definition": {
"type": "WRITE-METADATA",
"values": [
{
"path": "/1/0/7",
"metadata": [
{
"name": "pmin",
"value": "20"
},
{
"name": "gt",
"value": "50"
},
{
"name": "lt"
}
]
}
],
"policy": {"attempts" : 5}
}
}
- action
-
-
twin-operationaction will send a TWIN operation request to the device.
-
- definition
-
-
typeWRITE-METADATA : update metadata (set, update, reset). -
valuesValues to set. -
policy.attempts(optional) defines the maximal number of attempts until the operation is successfully completed
-
LwM2M Twin operation statuses
The following table shows how the twin operation statuses are converted into sequence statuses
Twin operation status |
Resulting status in the sequence |
PENDING |
if it is the first operation: PENDING, if not: IN_PROGRESS |
SENT |
IN_PROGRESS |
RETRYING |
IN_PROGRESS |
CANCELED |
CANCELED |
EXPIRED |
FAILURE |
FAILED |
FAILURE |
OK |
if it is the last operation: SUCCESS, if not: PENDING and the sequence moves onto the next operation |
LwM2M Twin observations
LwM2M Twin add observation
Example of twin add observation definition:
{
"action": "twin-add-observation",
"definition": {
"paths": [
"/1",
"/3/0",
"/3442/0/110",
"/3442/0/1110/0"
],
"name": "myObservation"
}
}
- action
-
-
twin-add-observationaction will send a TWIN add observation request to the device.
-
- definition
-
-
pathsPaths of attribute, attribute instance, object instance or all the object instances of an object to observe. -
namecustomized name for the observation
-
The following table shows how the Twin add observation statuses are converted into sequence statuses
Twin observation status |
Resulting status in the sequence |
PENDING |
if it is the first operation: PENDING, if not: IN_PROGRESS |
FAILED |
FAILURE |
OBSERVING |
if it is the last operation: SUCCESS, if not: PENDING and the sequence moves onto the next operation |
Campaign target (idList)
Campaign devices targets: either idList or filterQuery (exclusively).
idList is a flat list of devices identifiers.
Devices are identified using a URN identifier.
The format of this identifier must be urn:lo:nsid:{ns}:{id} with
-
nsthe target device identifier namespace -
idthe target device identifier
idList is not compatible with dynamicallyAddEligibleDevice option.
Below is an example of campaign targets definition using idList:
"targets":{
"idList":[
"urn:lo:nsid:namespace:device1",
"urn:lo:nsid:namespace:device2"
]
}
Campaign target (filterQuery RSQL)
filterQuery: Device filter expression to target devices using RSQL notation. Supported device properties are tags, properties, groupId,groupPath, connector . Supported RSQL operators are ==, !=, =in=, =out=, =lt=, =le=, =gt=, =ge=, and, or.
Below is an example of campaign targets definition using filterQuery:
"targets": {"filterQuery": "groupPath==/"}
| desc | syntax |
|---|---|
Logical AND |
; or and |
Logical OR |
, or or |
Equal to |
== |
Not equal to |
!= |
Less than |
=lt= or < |
Less than or equal to |
=le= or ⇐ |
Greater than operator |
=gt= or > |
Greater than or equal to |
=ge= or >= |
In |
=in= |
Not in |
=out= |
Below are example of filterQuery values.
-
Filter using
tags
tags=in=(FUT,TEST1)
For example, devices with at least tags "FUT" and "TEST1" whatever the order or additional tags
-
Filter on
properties
properties.mykey=in=(enum1, enum3) properties.mykey==toto
-
Filter on
groups
groupId=in=(1224,1234) groupId==1234 groupPath=in=(/FR, /EN)
-
Filter on
connector
connector==lwm2m
-
Filter with and and or conditions :
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
Campaign creation examples
Below are examples of campaign definition:
POST /api/v0/deviceMgt/campaigns
{
"name":"campaign1",
"description":"A campaign that configures parameters",
"planning":{
"startDate":"2017-07-01T00:00:00Z",
"endDate":"2017-07-23T23:59:59Z"
},
"targets":{
"idList":[
"urn:lo:nsid:namespace:device1",
"urn:lo:nsid:namespace:device2"
]
},
"operations":[
{
"action":"configure",
"definition":{
"assetParameters":{
"param1":{
"type":"INT32",
"valueInt32":1234
}
}
}
}
]
}
foo tagPOST /api/v0/deviceMgt/campaigns
{
"name":"campaign2",
"description":"A campaign that sends a command",
"planning":{
"startDate":"2017-07-01T00:00:00Z",
"endDate":"2017-07-23T23:59:59Z"
},
"options": {
"dynamicallyAddEligibleDevice": true
},
"targets": {"filterQuery": "tags=in=(foo)"},
"operations":[
{
"action":"command",
"definition":{
"event":"reset",
"data":{
"delay":"5000"
}
}
}
]
}
2 retries max)POST /api/v0/deviceMgt/campaigns
{
"name":"campaign3",
"description":"A campaign that updates a resource",
"planning":{
"startDate":"2017-07-01T00:00:00Z",
"endDate":"2017-07-23T23:59:59Z"
},
"targets":{
"idList":[
"urn:lo:nsid:namespace:device1",
"urn:lo:nsid:namespace:device2"
]
},
"operations":[
{
"action":"resource",
"definition":{
"resourceId":"firmware.bin",
"targetVersion":"1.1",
"maxRetry": 2,
"metadata" : {
"secured" : true
}
}
}
]
}
Campaign reporting
Once a campaign is created, a fleet manager can monitor the state of a campaign.
A campaign can have one of the statuses described below:
- SCHEDULED
-
The campaign has not yet started
- RUNNING
-
The campaign is in progress
- COMPLETE
-
The campaign is finished and all devices ended their sequence in success
- INCOMPLETE
-
The campaign is finished but some devices could not be configured
- SERVER_ERROR
-
An internal error occurred in the platform and the campaign could not be completed
- CANCELING
-
The campaign is waiting for running sequences to end, sequences that have not started yet will not start
- CANCELED
-
The campaign was canceled and some devices might not have been configured
The possible statuses for a device are presented below:
- notStarted
-
No operation executed on the device
- pending
-
The operation is recorded and waiting to be process by the device (soft cancel is still possible)
- inProgress
-
The operation is being processed by the device (soft cancel is no more possible)
- success
-
All operations were successfully executed on the device
- failure
-
One operation of the sequence failed, so the remaining operations (if any) were not executed
- canceled
-
The sequence was canceled before the end of all operations
Campaign cancelation
A campaign can be canceled with the following REST API endpoint:
PUT /api/v0/deviceMgt/campaigns/{campaignId}/cancel
If the campaign is already running, canceling it will set its state to CANCELING and the campaign will cancel pending sequences and wait for in progress sequences to end.
Then the campaign state will switch to CANCELED.
To abort in progress sequences, the force flag can be used.
PUT /api/v0/deviceMgt/campaigns/{campaignId}/cancel
force = true
Campaign deletion
A campaign can be deleted with the following REST API endpoint:
DELETE /api/v0/deviceMgt/campaigns/{campaignId}
If the campaign is in RUNNING or CANCELING state, it cannot be deleted.
In this case the force flag can be used to execute a forced cancelation and automatically delete the campaign once it is in CANCELED state.
DELETE /api/v0/deviceMgt/campaigns/{campaignId}
force = true
Global report
The global report indicates the campaign definition, the current status of a campaign and statistics about the number of devices with a given status.
GET /api/v0/deviceMgt/campaigns/{campaignId}
{
"name":"campaign1",
"description":"A campaign that configures parameters",
"planning":{
"startDate":"2017-07-01T00:00:00Z",
"endDate":"2017-07-23T23:59:59Z"
},
"targets":{
"idList":[
"urn:lo:nsid:namespace:device1",
"urn:lo:nsid:namespace:device2"
]
},
"operations":[
{
"action":"configure",
"definition":{
"assetParameters":{
"param1":{
"type":"INT32",
"valueInt32":1234
}
}
}
}
],
"numberOfTargets":2,
"totalTargetsPerStatus":{
"notStarted":0,
"pending":0,
"inProgress":1,
"failed":0,
"success":1,
"canceled":0
},
"campaignStatus":"RUNNING",
"created":"2017-06-01T00:00:00Z",
"updated":"2017-07-01T00:00:00Z"
}
Detailed report
The detailed report gives the status of each device in a campaign. The status property gives the status for the whole sequence of operations. The detailed report also indicates the status of each operation (operation reports are ordered just like in the campaign definition).
- operationStatus
-
Exact status reported by the device manager (the list of possible values depends on the type of operation). A special value notStarted is used when the operation is not yet started.
- operationId
-
Identifier returned by the device manager when the campaign manager created the operation
- started
-
Date when the operation was started
- updated
-
Last time the operation report was updated
- ended
-
Date when the operation was finished
- currentRetry
-
-
(Option) Retry attempt count of the latest operation executed.
-
For example, an
operationStatusequals toOK(orDONE) andcurrentRetryequals to1means that operation first failed, but the first retry attempt was a success.
-
GET /api/v0/deviceMgt/campaigns/{campaignId}/targets
{
"page":0,
"size":10,
"totalCount":2,
"data":[
{
"device":"urn:lo:nsid:namespace:id1",
"status":"inProgress",
"created":"2017-07-01T16:12:21.000Z",
"updated":"2017-07-01T16:12:21.000Z",
"operations":[
{
"action":"configure",
"operationStatus":"OK",
"started":"2017-07-01T16:20:21.000Z",
"updated":"2017-07-01T16:25:21.000Z",
"ended":"2017-07-01T16:25:21.000Z"
},
{
"action":"command",
"operationStatus":"SENT",
"operationId":"12345",
"started":"2017-07-01T16:30:21.000Z",
"updated":"2017-07-01T16:31:21.000Z"
},
{
"action":"resource",
"operationStatus":"notStarted"
}
]
},
{
"device":"urn:lo:nsid:namespace:id2",
"status":"success",
"created":"2017-07-01T16:12:21.000Z",
"updated":"2017-07-01T16:12:21.000Z",
"operations":[
{
"action":"configure",
"operationStatus":"OK"
"started":"2017-07-01T16:20:21.000Z",
"updated":"2017-07-01T16:25:21.000Z",
"ended":"2017-07-01T16:25:21.000Z"
},
{
"action":"command",
"operationStatus":"PROCESSED",
"operationId":"6789",
"started":"2017-07-01T16:30:21.000Z",
"updated":"2017-07-01T16:31:21.000Z"
},
{
"action": "resource",
"operationStatus": "DONE",
"operationId": "X11_firmware",
"started": "2017-07-01T16:30:21.000Z",
"updated": "2017-07-01T16:38:21.000Z",
"ended": "2017-07-01T16:38:21.000Z",
"currentRetry": 1
}
]
}
]
}