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

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

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)

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.

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
@startuml UC1

scale 0.8
skinparam style strictuml

participant CUSTOMER #LightGreen
participant "LiveObjects" as LO
participant "Device" as DEV


activate LO
note over CUSTOMER
Create a new operation
end note
CUSTOMER -> LO : POST /api/v1/deviceMgt/devices/{deviceId}/twin/operations
note over LO
Validate and store PENDING operation
end note
LO -> CUSTOMER : 

== Device is now here ==
activate DEV
DEV -> LO : lwm2m: register
note over LO
update PENDING device operation(s) to SENT
end note
LO -> DEV : send operation(s)
DEV -> LO : Op1 response
note over LO
update Op1 to OK
end note
DEV -> LO : Op2 response FAILED event (not retryable case or max attempts reached))
note over LO
update Op2 to FAILED
end note
DEV -> LO : Op3 response FAILED event (retryable case)
note over LO
update Op3 to RETRYING
end note

CUSTOMER -> LO : GET /api/v1/deviceMgt/devices/{deviceId}/twin/operations
LO -> CUSTOMER : 


deactivate LO
deactivate DEV

@enduml

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
@startuml TwinOperationsStatus

scale 0.8
title Twin Operations Status

[*] --> PENDING : user creation (north API)

state PENDING {
  PENDING : Device is not listening yet
  PENDING : Waiting for Capability=TRUE
}

PENDING --> EXPIRED : timeout (x days)
PENDING --> CANCELLED : user cancellation
PENDING --> SENT : Twin Capability goes TRUE

state SENT {
  SENT : Connector is processing
  SENT : the operation
}

SENT --> OK : Successful response
SENT --> IS_RETRYABLE : Error response
SENT --> IS_TIMEOUT_RETRYABLE : timeout (y minutes)

state IS_RETRYABLE <>
state IS_TIMEOUT_RETRYABLE <>

IS_RETRYABLE --> RETRYING : retryable and\nmax attempts not reached
IS_RETRYABLE --> FAILED : else

IS_TIMEOUT_RETRYABLE --> RETRYING : max attempts\nnot reached
IS_TIMEOUT_RETRYABLE --> EXPIRED : else

RETRYING --> SENT : Twin Capability\ngoes TRUE
RETRYING --> EXPIRED : timeout (x days)

state CANCELLED #Pink
state EXPIRED #Pink
state FAILED #Pink
state OK #PaleGreen
state RETRYING #Orange

@enduml
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.

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
@startuml UC1
skinparam style strictuml

scale 0.8
participant CUSTOMER #LightGreen
participant "DeviceTwin Service" as TWIN
participant "DM Inventory Service" as DM
participant "LWM2M Service" as LW

activate TWIN
activate DM
activate LW
note over TWIN
Operation(s) has been previously in RETRYING status
end note
== Device is now here ==
LW -> DM : node status ONLINE
DM -> TWIN : twin capability=true
TWIN -> TWIN : onCapabilityUpdated
note over TWIN
update RETRYING device operation(s) to SENT
end note
TWIN -> LW : send operation(s)
LW -> TWIN : operation Op1 response OK event
note over TWIN
update Op1 to OK
end note
LW -> TWIN : operation Op2 response FAILED event (not retryable case or max attempts reached)
note over TWIN
update Op2 to FAILED
end note
LW -> TWIN : operation Op3 response FAILED event (retryable case) and max attempts not reached)
note over TWIN
update Op3 to RETRYING
end note

deactivate TWIN
deactivate LW
deactivate DM

@enduml

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.