The upcoming release of Eclipse Ditto version 2.3.0 will support sending commands via the HTTP API directly to devices using the live channel by just adding the channel=live query parameter to the same HTTP API request which would target the twin.

HTTP Live channel

Ditto supports sending all kind of Thing commands via the live channel directly to devices. When sending a live command to a device, the device is responsible for sending a correlated and correct response in Ditto Protocol.

Ditto supports two types of channels for communication.

  • twin: The default value of the channel parameter is twin to communicate with the persisted twin representation.
  • live: The channel parameter can be changed to live to communicate with the real device.

When using the twin channel, the command is routed to the Ditto backend and handled by the twin persistence. Before using the live channel, it is necessary to create the digital twin of the device in the Ditto backend.

If the live channel is used, the command is directly routed to the device. In this case the device is responsible for answering the command and sending back a response. In case no response is sent back, the Ditto HTTP API is responding with 408 Request Timeout.
The default timeout for live commands is 10s but it can be changed by setting the timeout parameter to the desired value.

Ditto ensures that the correlation ID, entity ID, path and command response type of the command response is the same as in the sending command. If this is not the case, Ditto is dropping the response and the caller of the HTTP request will get a 408 Request Timeout with a message that the timeout was caused by an incompatible command response from the device.

Permissions for live commands

Sending live commands to devices is restricted by the policy of the thing.
Thus Ditto ensures that only authorized parties with WRITE permission are able to send commands or messages.
Ditto also filters responses from the device based on the policy. This ensures that the requester only gets the data where he/she has READ permission on.

For retrieve commands, the authenticated subject needs to have (at least partial) READ permission at the resource which is requested.
In case a RetrieveThing (via HTTP a GET /api/2/things/<thing-id>) command is sent to a real device and the requester only has partial READ permission on the thing, the response is filtered based on the policy and only the fields where READ permission is granted are returned.

Live commands via HTTP API

When using the HTTP API the channel parameter can either be specified via HTTP Header or via HTTP query parameter.
In the examples below both ways are possible to specify the channel parameter.

Live command with HTTP Header

curl -X GET -H 'channel: live' -H 'timeout: 30s' /api/2/things/org.eclipse.ditto:coffeebrewer'

Live command with HTTP query parameter

curl -X GET /api/2/things/org.eclipse.ditto:coffeebrewer?channel=live&timeout=30s'

Example

The following section provides an example how to use the HTTP live channel together with the Ditto Java client.

For demonstration purpose, we assume that the thing with ID org.eclipse.ditto:outdoor-sensor already exists.

In this example we want to retrieve the live state of the device by sending a RetrieveThing command via the live channel directly to the device.

Permissions to execute the example

For this example, the authenticated subject has READ and WRITE permissions on the complete thing resource to send the command and retrieve the full response.

Executing the example

When sending a command over the live channel to a device, the device needs to take action and send back a response.
The response from the device is routed back to the initial requester of the live command at the HTTP API.

In this example the Ditto Java Client acts as device and sends back the response.
The following snippet shows how to register for retrieve thing live commands and send back a RetrieveThingResponse.

String thingId = "org.eclipse.ditto:outdoor-sensor";
String featureId = "environment-sensor";
Attributes attributes = Attributes.newBuilder()
  .set("location", "outdoor in the woods")
  .build();
Feature feature = ThingsModelFactory.newFeatureBuilder()
  .properties(ThingsModelFactory.newFeaturePropertiesBuilder()
    .set("temperature", 9.2)
    .set("humidity", 56.3)
    .build())
  .withId(featureId)
  .build();

Thing thing = ThingsModelFactory.newThingBuilder()
  .setId(thingId)
  .setFeature(feature)
  .setAttributes(attributes)
  .build();

// initialize the ditto-client and startConsumption() of live commands
DittoClient dittoClient = ... ;

dittoClient.live()
  .forId(thingId)
  .handleRetrieveThingCommandsFunction(retrieveThingLiveCommand -> {
      return retrieveThingLiveCommand.answer()
                  .withResponse(response -> response.retrieved(thing));
  });

When the above shown code snippet is running and the following HTTP request is sent out:

curl -X GET /api/2/things/org.eclipse.ditto:outdoor-sensor?channel=live&timeout=15s

The received HTTP response payload should look like this:

{
  "thingId": "org.eclipse.ditto:outdoor-sensor",
  "_namespace": "org.eclipse.ditto",
  "attributes": {
    "location": "outdoor in the woods"
  },
  "features": {
    "environment-sensor": {
      "properties": {
        "temperature": 9.2,
        "humidity": 56.3
      }
    }
  }
}

Feedback?

Please get in touch if you have feedback or questions towards this new functionality.



Ditto


The Eclipse Ditto team