Skip to content

Commit

Permalink
review: worked on "http live channel" blog post; adjusted Ditto relea…
Browse files Browse the repository at this point in the history
…se version to 2.3.0

* fixed customscripts.js which broke displaying the "toc" in blogposts

Signed-off-by: Thomas Jaeckle <thomas.jaeckle@bosch.io>
  • Loading branch information
thjaeckle committed Nov 24, 2021
1 parent 8ae818b commit 375333e
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 77 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: "HTTP Live channel"
title: "Sending live channel commands via HTTP to devices"
published: true
permalink: 2021-11-26-http-live-channel.html
layout: post
Expand All @@ -10,129 +10,143 @@ sidebar: false
toc: true
---

The upcoming release of Eclipse Ditto **version 2.2.0** will support sending commands directly to devices at the
HTTP API via the `live` channel parameter.
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](protocol-twinlive.html#live) by just adding the `channel=live`
query parameter to the same HTTP API request which would target the [twin](protocol-twinlive.html#twin).

## HTTP Live channel
Ditto supports sending all kind of [Thing commands](protocol-specification-things.md#commands) via

Ditto supports sending all kind of [Thing commands](protocol-specification-things.html#commands) via
the `live` channel directly to devices.
When sending a `live` command to a device, the device is responsible for sending a response.
When sending a `live` command to a device, the device is responsible for sending a correlated and correct response
in [Ditto Protocol](protocol-overview.html).

Ditto supports two types of `channel` for communication.
Ditto supports two types of `channel`s for communication.

* The default value of the channel parameter is `twin`, to communicate with the **digital twin** representation.
* The `channel` parameter can be changed to `live`, to communicate with the real device.
* [twin](protocol-twinlive.html#twin): The default value of the channel parameter is `twin`
to communicate with the persisted **twin** representation.
* [live](protocol-twinlive.html#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 **digital twin**.
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 send back, Ditto
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.
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 `408 Request Timeout` with a message that the timeout was caused by an incompatible
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.
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.
where he/she has `READ` permission on.

For retrieve commands, the authorized subject needs to have (at least partial) READ permission at the resource which
is requested. In case a `RetrieveThing` command is send to a real device and the requester only have partial READ
permission on the thing. Then the `RetrieveThingResponse` is filtered based on the policy and only the fields where
READ permission is granted are returned.
For retrieve commands, the [authenticated subject](basic-auth.html#authenticated-subjects) 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.

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
```

```bash
curl -X GET -H 'channel: live' -H 'timeout: 30s' /api/2/things/org.eclipse.ditto:coffeebrewer'
```
#### Live command with HTTP query parameter
```
```bash
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 authorized subject could have READ and WRITE permissions on the complete thing resource to send
the command and retrieve the full response.
### Permissions to execute the example

For this example, the [authenticated subject](basic-auth.html#authenticated-subjects) 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.

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](client-sdk-java.html) acts as device and sends back the response.
In this example the [Ditto Java Client](client-sdk-java.html) 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`.

```java
final String THING_ID = "org.eclipse.ditto:outdoor-sensor";
final String FEATURE_ID = "environment-sensor";
final Attributes ATTRIBUTES = Attributes.newBuilder()
.set("location", "outdoor in the woods")
.build();
final Feature FEATURE = ThingsModelFactory.newFeatureBuilder()
.properties(ThingsModelFactory.newFeaturePropertiesBuilder()
.set("temperature", 9.2)
.set("humidity", 56.3)
.build())
.withId(FEATURE_ID)
.build();

final Thing THING = ThingsModelFactory.newThingBuilder()
.setId(THING_ID)
.setFeature(FEATURE)
.setAttributes(ATTRIBUTES)
.build();
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
final DittoClient dittoClient = ... ;
DittoClient dittoClient = ... ;

dittoClient.live()
.forId(thingId)
.handleRetrieveThingCommandsFunction(retrieveThingLiveCommand -> {
return retrieveThingLiveCommand.answer()
.withResponse(response -> response.retrieved(thing));
});
.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 send out
```
When the above shown code snippet is running and the following HTTP request is sent out:
```bash
curl -X GET /api/2/things/org.eclipse.ditto:outdoor-sensor?channel=live&timeout=15s
```

The response should look like this:
The received HTTP response payload should look like this:
```json
{
"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
}
}
"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
}
}
}
}
```

Expand Down
20 changes: 11 additions & 9 deletions documentation/src/main/resources/js/customscripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,19 @@ $(function () {
function changeSelectedDocVersionDropdownSelection(element) {
var pathName = window.location.pathname;

var versionOptions = element.options;
for (var i = 0; i < versionOptions.length; i++) {
var versionValue = versionOptions[i].value;
if ((versionValue !== "") && pathName.startsWith("/ditto/"+versionValue+"/")) {
$("#docVersion").val(versionValue).change();
return;
if (element) {
var versionOptions = element.options;
for (var i = 0; i < versionOptions.length; i++) {
var versionValue = versionOptions[i].value;
if ((versionValue !== "") && pathName.startsWith("/ditto/"+versionValue+"/")) {
$("#docVersion").val(versionValue).change();
return;
}
}
// fallback: dev with "empty" version value:
$("#docVersion").val("").change();
$("#dev-warning").show();
}
// fallback: dev with "empty" version value:
$("#docVersion").val("").change();
$("#dev-warning").show();
}

function changeSelectedDocVersion() {
Expand Down

0 comments on commit 375333e

Please sign in to comment.