blob: 84b6ff01abcfea2340478b70ff94942e5de0d492 [file] [log] [blame]
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="/packages/assets/bootstrap/bootstrap.min.css">
<title>Take a tour</title>
<link rel="stylesheet" href="/packages/assets/css/style.css">
<script src="/packages/assets/js/code.js"></script>
<meta name="twitter:card" content="summary"/>
<meta name="twitter:image" content="https://eclipse.org/packages/images/icon/twitter_icon.png"/>
<meta name="twitter:title" content="Cloud2Edge | Take a tour"/>
<meta name="twitter:description" content="Take a tour once you installed the Cloud2Edge package."/>
<link rel="icon" type="image/svg+xml" href="/packages/images/icon/icon.svg" sizes="any">
<link rel="icon" href="/packages/images/icon/icon.png" sizes="192x192">
<link rel="apple-touch-icon-precomposed" href="/packages/images/icon/icon_apple.png" sizes="180x180">
</head>
<body>
<header>
<nav class="navbar navbar-expand-md fixed-top navbar-light bg-light">
<div class="container">
<a class="navbar-brand" href="/packages/">
<img src="/packages/images/icon_brand_navbar.svg" width="30" height="30" alt="Eclipse IoT Packages™">
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarCollapse">
<ul class="navbar-nav mr-auto"><li class="nav-item">
<a
class="nav-link"
href="/packages/">Home</a>
</li>
<li class="nav-item">
<a
class="nav-link"
href="/packages/about/">About</a>
</li>
<li class="nav-item">
<a
class="nav-link"
href="/packages/faq/">FAQ</a>
</li>
<li class="nav-item">
<a
class="nav-link"
href="/packages/contribute/">Contribute</a>
</li>
<li class="nav-item">
<a
class="nav-link"
href="/packages/prereqs/">Prerequisites</a>
</li>
<li class="nav-item">
<a
class="nav-link"
href="/packages/repository/">Repository</a>
</li>
</ul>
</div>
</div>
</nav></header>
<main id="main" role="main" >
<div><div class="container mt-5">
<div class="row">
<div class="col-12 col-sm-9 col-xl-8">
<h1>Cloud2Edge</h1>
<p class="lead">A package connecting and managing sensor style devices. Connecting sensors to the cloud and processing data with a digital twin platform.</p></div>
<div class="col-12 col-sm-3 col-xl-4 d-flex flex-sm-row-reverse">
<img alt="Page logo" src="/packages/packages/cloud2edge/images/c2e-logo.svg" class="img-fluid m-lg-3 d-block align-self-center " style="max-height: 10rem;"/>
</div>
</div>
</div>
</div>
<div class="container">
<nav class="nav nav-pills nav-fill mt-2 mb-5"><a class="nav-item nav-link " href="/packages/packages/cloud2edge/">Overview</a><a class="nav-item nav-link " href="/packages/packages/cloud2edge/installation/">Installation</a><a class="nav-item nav-link " href="/packages/packages/cloud2edge/learn/">Learn more</a><a class="nav-item nav-link active" href="/packages/packages/cloud2edge/tour/">Take a tour</a></nav>
<div class="row">
<div class="col-12 col-md-8 col-lg-9">
<div role="alert" class="alert alert-warning"><h4 class="alert-heading">Under construction </h4>
This tutorial is still under construction, and not finished yet.
Of course, you are still welcome to try it. Take a look and give some feedback.
<hr /><p class="mb-0">
Just be aware that some content might still be missing, change over time
or that you might experience some issues when testing.
</p>
</div>
<h2 id="preparing-the-environment">Preparing the environment</h2>
<p>The following examples will use information which depends on your
environment. All of this information is listed in this section and will be
set as environment variables so that all commands can easily make use
of those variables. Note that you will need to set the environment variables
in every command shell separately.</p>
<nav><div class="nav nav-tabs" role="tablist"><a class="nav-item nav-link active" data-toggle="tab" id="variants-1-0-tab" href="#variants-1-0" aria-controls="variants-1-0">Kubernetes</a><a class="nav-item nav-link" data-toggle="tab" id="variants-1-1-tab" href="#variants-1-1" aria-controls="variants-1-1">OpenShift</a></div></nav>
<div class="tab-content">
<div class="tab-pane active show" id="variants-1-0" role="tabpanel" aria-labelledby="variants-1-0-tab">
<p><br />
Download the <a href="../scripts/setCloud2EdgeEnv.sh">setCloud2EdgeEnv script</a> and use it
to set environment variables for the Cloud2Edge package’s service endpoints.</p>
<div class="clipboard"><pre><code>RELEASE=c2e
NS=cloud2edge
./setCloud2EdgeEnv.sh $RELEASE $NS</code></pre></div>
</div>
<div class="tab-pane" id="variants-1-1" role="tabpanel" aria-labelledby="variants-1-1-tab">
<div class="clipboard"><pre><code>NS=cloud2edge
RELEASE=c2e
DEVICE_REGISTRY_URL=https://$(oc get -n $NS route ${RELEASE}-service-device-registry-https --template='{{.spec.host}}')
HTTP_ADAPTER_URL=$(oc get -n $NS route ${RELEASE}-adapter-http-vertx-sec --template='{{.spec.host}}')
HTTP_ADAPTER_PORT=443</code></pre></div>
</div>
</div>
<h2 id="publishing-telemetry-data">Publishing telemetry data</h2>
<p>The Cloud2Edge package comes with a pre-provisioned example device that we will use to publish
some telemetry data via Hono’s HTTP protocol adapter. The data will automatically be forwarded to Ditto
where the device’s twin representation will be updated with the data published by the device.</p>
<p>The demo device’s digital twin supports a temperature property which will be set to 45
by means of the following command:</p>
<div class="clipboard"><pre><code>curl -i -u demo-device@org.eclipse.packages.c2e:demo-secret -H 'application/json' --data-binary '{
"topic": "org.eclipse.packages.c2e/demo-device/things/twin/commands/modify",
"headers": {},
"path": "/features/temperature/properties/value",
"value": 45
}' http://${HTTP_ADAPTER_IP}:${HTTP_ADAPTER_PORT_HTTP}/telemetry</code></pre></div>
<h2 id="retrieving-the-digital-twins-current-state">Retrieving the digital twin’s current state</h2>
<p>The updated state of the digital twin can then be retrieved using:</p>
<div class="clipboard"><pre><code>curl -u ditto:ditto -w '\n' http://$DITTO_API_IP:$DITTO_API_PORT_HTTP/api/2/things/org.eclipse.packages.c2e:demo-device</code></pre></div>
<p>Alternatively you can also use the following command to subscribe to Ditto’s
stream of thing update events:</p>
<div class="clipboard"><pre><code>curl --http2 -u ditto:ditto -H 'Accept:text/event-stream' -N http://$DITTO_API_IP:$DITTO_API_PORT_HTTP/api/2/things</code></pre></div>
<h2 id="sending-a-command-to-the-device-via-its-digital-twin">Sending a command to the device via its digital twin</h2>
<p>Ditto digital twin may also be used to send a command down to the device connected at Hono using.</p>
<div class="clipboard"><pre><code>curl -i -X POST -u ditto:ditto -H 'Content-Type: application/json' -w '\n' --data '{
"water-amount": "3liters"
}' http://$DITTO_API_IP:$DITTO_API_PORT_HTTP/api/2/things/org.eclipse.packages.c2e:demo-device/inbox/messages/start-watering?timeout=0</code></pre></div>
<p>Specifying the <code class="language-plaintext highlighter-rouge">timeout=0</code> parameter indicates that the HTTP request will directly be accepted and Ditto does not wait
for a response.</p>
<p>If Ditto shall wait for a response, responding with the response from the device at the HTTP level, simply increase the
timeout to the amount of seconds to wait:</p>
<div class="clipboard"><pre><code>curl -i -X POST -u ditto:ditto -H 'Content-Type: application/json' -w '\n' --data '{
"water-amount": "3liters"
}' http://$DITTO_API_IP:$DITTO_API_PORT_HTTP/api/2/things/org.eclipse.packages.c2e:demo-device/inbox/messages/start-watering?timeout=60</code></pre></div>
<h3 id="receiving-a-command-at-the-device">Receiving a command at the device</h3>
<p>The device may receive a command by specifying a <code class="language-plaintext highlighter-rouge">ttd</code> when e.g. sending telemetry via HTTP to Hono:</p>
<div class="clipboard"><pre><code>curl -i -u demo-device@org.eclipse.packages.c2e:demo-secret -H 'hono-ttd: 50' -H 'application/json' -w '\n' --data '{
"topic": "org.eclipse.packages.c2e/demo-device/things/twin/commands/modify",
"headers": {},
"path": "/features/temperature/properties/value",
"value": 45
}' http://${HTTP_ADAPTER_IP}:${HTTP_ADAPTER_PORT_HTTP}/telemetry</code></pre></div>
<p>An example response for the device containing the command sent via the Ditto twin (see previous step for sending the
command) is:</p>
<p><details><summary>Example of a received command at the device</summary><div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>HTTP/1.1 200 OK
hono-command: start-watering
hono-cmd-req-id: 024d84b1ceb-797b-45f5-bc87-78e9b5396645replies
content-type: application/json
content-length: 516
{"topic":"org.eclipse.packages.c2e/demo-device/things/live/messages/start-watering","headers":{"correlation-id":"d84b1ceb-797b-45f5-bc87-78e9b5396645","x-forwarded-for":"10.244.0.1","version":2,"timeout":"0","x-forwarded-user":"ditto","accept":"*/*","x-real-ip":"10.244.0.1","x-ditto-dummy-auth":"nginx:ditto","host":"172.17.0.2:30385","content-type":"application/json","timestamp":"2020-02-28T08:04:43.518+01:00","user-agent":"curl/7.58.0"},"path":"/inbox/messages/start-watering","value":{"water-amount":"3liters"}}
</code></pre></div> </div>
</div></details></p>
<h3 id="responding-to-a-command-at-the-device">Responding to a command at the device</h3>
<p>In order to answer to a command, the device can send its answer in Ditto Protocol back to Hono via HTTP.</p>
<p>The response has to be correlated twice:</p>
<ul>
<li>once for Hono in the URL: please replace the placeholder <code class="language-plaintext highlighter-rouge">insert-hono-cmd-req-id-here</code> with the <code class="language-plaintext highlighter-rouge">hono-cmd-req-id</code>
HTTP header value from the received command.</li>
<li>once for Ditto in the Ditto Protocol payload: please replace the placeholder <code class="language-plaintext highlighter-rouge">insert-ditto-correlation-id-header-here</code>
with the <code class="language-plaintext highlighter-rouge">"correlation-id"</code> value from the received Ditto Protocol message’s <code class="language-plaintext highlighter-rouge">"headers"</code> object.</li>
</ul>
<div class="clipboard"><pre><code>curl -i -X PUT -u demo-device@org.eclipse.packages.c2e:demo-secret -H "content-type: application/json" --data-binary '{
"topic": "org.eclipse.packages.c2e/demo-device/things/live/messages/start-watering",
"headers": {
"content-type": "application/json",
"correlation-id": "insert-ditto-correlation-id-header-here"
},
"path": "/inbox/messages/start-watering",
"value": {
"starting-watering": true
},
"status": 200
}' http://${HTTP_ADAPTER_IP}:${HTTP_ADAPTER_PORT_HTTP}/command/res/org.eclipse.packages.c2e/org.eclipse.packages.c2e:demo-device/insert-hono-cmd-req-id-here?hono-cmd-status=200</code></pre></div>
<p>An example message response (omitting some additional HTTP headers) at the Ditto twin which waited for the command
e.g. with a <code class="language-plaintext highlighter-rouge">timeout=60</code> is:</p>
<p><details><summary>Example of a twin message response</summary><div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 26
correlation-id: 715cb667-7750-4451-969e-6f8c735129ef
{"starting-watering":true}
</code></pre></div> </div>
</div></details></p>
<h2 id="working-with-devices">Working with devices</h2>
<p>The next sections will create a new tenant in Hono, register a device for it and create a digital twin for it in Ditto.</p>
<p>In order to <em>link</em> Hono devices to Ditto digital twins (a.k.a. things), it is assumed that Hono device and Ditto thing
always have the same id, starting with a namespace (e.g. in reverse domain notation), followed by a colon and a name,
e.g.: <code class="language-plaintext highlighter-rouge">org.acme:my-device</code>.</p>
<h3 id="create-a-new-tenant">Create a new tenant</h3>
<p>Create a new tenant named <code class="language-plaintext highlighter-rouge">my-tenant</code> in Hono:</p>
<div class="clipboard"><pre><code>curl -i -X POST http://${REGISTRY_IP}:${REGISTRY_PORT_HTTP}/v1/tenants/my-tenant</code></pre></div>
<p>This should return a result of <code class="language-plaintext highlighter-rouge">201 Created</code>.</p>
<p><details><summary>Example of a successful result</summary><div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>HTTP/1.1 201 Created
etag: be547a07-4a03-4c43-a274-d02f63f8d467
location: /v1/tenants/my-tenant
content-type: application/json; charset=utf-8
content-length: 12
{"id":"my-tenant"}
</code></pre></div> </div>
</div></details></p>
<h3 id="register-a-new-device">Register a new device</h3>
<p>Next we can register a new device, named <code class="language-plaintext highlighter-rouge">org.acme:my-device-1</code> for the tenant we just created:</p>
<div class="clipboard"><pre><code>curl -i -X POST http://${REGISTRY_IP}:${REGISTRY_PORT_HTTP}/v1/devices/my-tenant/org.acme:my-device-1</code></pre></div>
<p>This should return a result of <code class="language-plaintext highlighter-rouge">201 Created</code>.</p>
<p><details><summary>Example of a successful result</summary><div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>HTTP/1.1 201 Created
etag: d48f4e13-b398-4c73-bbc3-5ac97a81b3e8
location: /v1/devices/iot/org.acme:my-device-1
content-type: application/json; charset=utf-8
content-length: 17
{"id":"org.acme:my-device-1"}
</code></pre></div> </div>
</div></details></p>
<h4 id="set-device-credentials">Set device credentials</h4>
<p>The device created has no credentials assigned. So it will not be possible for this
device to directly connect to the platform. This is ok for devices attached via
a <em>gateway device</em>, but we want this device to be able to connect, so the next step is
to assign a username/password combination:</p>
<div class="clipboard"><pre><code>curl -i -X PUT -H "Content-Type: application/json" --data '[
{
"type": "hashed-password",
"auth-id": "my-auth-id-1",
"secrets": [{
"pwd-plain": "my-password"
}]
}]' http://${REGISTRY_IP}:${REGISTRY_PORT_HTTP}/v1/credentials/my-tenant/org.acme:my-device-1</code></pre></div>
<p><details><summary>Example of a successful result</summary><div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>HTTP/1.1 204 No Content
etag: a7edc4b8-701a-4fe1-85c4-1717c0d24562
</code></pre></div> </div>
</div></details></p>
<h4 id="understanding-identities">Understanding identities</h4>
<p>The previous step assigned the credentials of <code class="language-plaintext highlighter-rouge">my-auth-id-1</code> and <code class="language-plaintext highlighter-rouge">my-password</code> to the device <code class="language-plaintext highlighter-rouge">org.acme:my-device-1</code>.</p>
<p>Please note that there is a difference between the <em>username</em> of the device (<code class="language-plaintext highlighter-rouge">my-auth-id-1</code>) and
the name of the device (<code class="language-plaintext highlighter-rouge">org.acme:my-device-1</code>). When connecting to e.g. the MQTT protocol adapter,
you will need to use the fully qualified username of <code class="language-plaintext highlighter-rouge">my-auth-id-1@my-tenant</code>
(<em>authentication id</em> and <em>tenant name</em>), rather than just the <em>device id</em> (<code class="language-plaintext highlighter-rouge">org.acme:my-device-1</code>).</p>
<p>The <em>authentication id</em> is only used for the authentication process. Later on, the messages will be marked
with the <em>device id</em> and the back end system isn’t aware of the <em>authentication id</em> anymore.</p>
<p>Of course you may use the same value for the <em>authentication id</em> and the <em>device id</em>. In this tutorial however,
we use distinct values to show the difference.</p>
<h3 id="create-a-new-connection-from-ditto-to-hono">Create a new connection from Ditto to Hono</h3>
<p>In order to create digital twins in Ditto for a newly added Hono tenant, a new connection has to be created.</p>
<p>The <code class="language-plaintext highlighter-rouge">NS</code> and <code class="language-plaintext highlighter-rouge">RELEASE</code> variables must still be set to the value you chose during the <a href="../installation/#install-the-package">installation</a>.
The documented defaults are:</p>
<div class="clipboard"><pre><code>NS=cloud2edge
RELEASE=c2e</code></pre></div>
<p>Please also configure your chosen Hono tenant name <a href="#create-a-new-tenant">when your created a new tenant</a> and extract
the Ditto devops password via <code class="language-plaintext highlighter-rouge">kubectl</code>:</p>
<div class="clipboard"><pre><code>HONO_TENANT=my-tenant
DITTO_DEVOPS_PWD=$(kubectl --namespace ${NS} get secret ${RELEASE}-ditto-gateway-secret -o jsonpath="{.data.devops-password}" | base64 --decode)</code></pre></div>
<p>Now, create the connection:</p>
<div class="clipboard"><pre><code>curl -i -X POST -u devops:${DITTO_DEVOPS_PWD} -H 'Content-Type: application/json' --data '{
"targetActorSelection": "/system/sharding/connection",
"headers": {
"aggregate": false
},
"piggybackCommand": {
"type": "connectivity.commands:createConnection",
"connection": {
"id": "hono-connection-for-'"${HONO_TENANT}"'",
"connectionType": "amqp-10",
"connectionStatus": "open",
"uri": "amqp://consumer%40HONO:verysecret@'"${RELEASE}"'-dispatch-router-ext:15672",
"failoverEnabled": true,
"sources": [
{
"addresses": [
"telemetry/'"${HONO_TENANT}"'",
"event/'"${HONO_TENANT}"'"
],
"authorizationContext": [
"pre-authenticated:hono-connection"
],
"enforcement": {
"input": "{{ header:device_id }}",
"filters": [
"{{ entity:id }}"
]
},
"headerMapping": {
"hono-device-id": "{{ header:device_id }}",
"content-type": "{{ header:content-type }}"
},
"replyTarget": {
"enabled": true,
"address": "{{ header:reply-to }}",
"headerMapping": {
"to": "command/'"${HONO_TENANT}"'/{{ header:hono-device-id }}",
"subject": "{{ header:subject | fn:default(topic:action-subject) | fn:default(topic:criterion) }}-response",
"correlation-id": "{{ header:correlation-id }}",
"content-type": "{{ header:content-type | fn:default('"'"'application/vnd.eclipse.ditto+json'"'"') }}"
},
"expectedResponseTypes": [
"response",
"error"
]
},
"acknowledgementRequests": {
"includes": [],
"filter": "fn:filter(header:qos,'"'"'ne'"'"','"'"'0'"'"')"
}
},
{
"addresses": [
"command_response/'"${HONO_TENANT}"'/replies"
],
"authorizationContext": [
"pre-authenticated:hono-connection"
],
"headerMapping": {
"content-type": "{{ header:content-type }}",
"correlation-id": "{{ header:correlation-id }}",
"status": "{{ header:status }}"
},
"replyTarget": {
"enabled": false,
"expectedResponseTypes": [
"response",
"error"
]
}
}
],
"targets": [
{
"address": "command/'"${HONO_TENANT}"'",
"authorizationContext": [
"pre-authenticated:hono-connection"
],
"topics": [
"_/_/things/live/commands",
"_/_/things/live/messages"
],
"headerMapping": {
"to": "command/'"${HONO_TENANT}"'/{{ thing:id }}",
"subject": "{{ header:subject | fn:default(topic:action-subject) }}",
"content-type": "{{ header:content-type | fn:default('"'"'application/vnd.eclipse.ditto+json'"'"') }}",
"correlation-id": "{{ header:correlation-id }}",
"reply-to": "{{ fn:default('"'"'command_response/'"${HONO_TENANT}"'/replies'"'"') | fn:filter(header:response-required,'"'"'ne'"'"','"'"'false'"'"') }}"
}
},
{
"address": "command/'"${HONO_TENANT}"'",
"authorizationContext": [
"pre-authenticated:hono-connection"
],
"topics": [
"_/_/things/twin/events",
"_/_/things/live/events"
],
"headerMapping": {
"to": "command/'"${HONO_TENANT}"'/{{ thing:id }}",
"subject": "{{ header:subject | fn:default(topic:action-subject) }}",
"content-type": "{{ header:content-type | fn:default('"'"'application/vnd.eclipse.ditto+json'"'"') }}",
"correlation-id": "{{ header:correlation-id }}"
}
}
]
}
}
}' http://${DITTO_API_IP}:${DITTO_API_PORT_HTTP}/devops/piggyback/connectivity</code></pre></div>
<h3 id="create-the-digital-twin">Create the digital twin</h3>
<p>In the previous steps a device was registered in Hono, now we want to create a digital twin for this device in Ditto.</p>
<h4 id="setup-a-common-policy">Setup a common policy</h4>
<p>In order to define common authorization information for all digital twins about to be created in Ditto, we first create
a policy with the id <code class="language-plaintext highlighter-rouge">org.acme:my-policy</code>:</p>
<div class="clipboard"><pre><code>curl -i -X PUT -u ditto:ditto -H 'Content-Type: application/json' --data '{
"entries": {
"DEFAULT": {
"subjects": {
"{{ request:subjectId }}": {
"type": "Ditto user authenticated via nginx"
}
},
"resources": {
"thing:/": {
"grant": ["READ", "WRITE"],
"revoke": []
},
"policy:/": {
"grant": ["READ", "WRITE"],
"revoke": []
},
"message:/": {
"grant": ["READ", "WRITE"],
"revoke": []
}
}
},
"HONO": {
"subjects": {
"pre-authenticated:hono-connection": {
"type": "Connection to Eclipse Hono"
}
},
"resources": {
"thing:/": {
"grant": ["READ", "WRITE"],
"revoke": []
},
"message:/": {
"grant": ["READ", "WRITE"],
"revoke": []
}
}
}
}
}' http://${DITTO_API_IP}:${DITTO_API_PORT_HTTP}/api/2/policies/org.acme:my-policy</code></pre></div>
<p>This should return a result of <code class="language-plaintext highlighter-rouge">201 Created</code> containing as response body of the created policy JSON.</p>
<p>The created policy may be used for just one digital twin or for many of them. Modifying it will adjust the authorization
configuration of all twins referencing this <em>policy id</em>.</p>
<h4 id="create-the-twin">Create the twin</h4>
<p>In order to create a digital twin in Ditto, we use the same <em>device id</em> already used for creating the device at Hono as
<em>thing id</em>: <code class="language-plaintext highlighter-rouge">org.acme:my-device-1</code>.<br />
Furthermore, we add a reference to the in the previous step created <em>policy id</em> in order to define the authorization
information of the twin:</p>
<div class="clipboard"><pre><code>curl -i -X PUT -u ditto:ditto -H 'Content-Type: application/json' --data '{
"policyId": "org.acme:my-policy",
"attributes": {
"location": "Germany"
},
"features": {
"temperature": {
"properties": {
"value": null
}
},
"humidity": {
"properties": {
"value": null
}
}
}
}' http://${DITTO_API_IP}:${DITTO_API_PORT_HTTP}/api/2/things/org.acme:my-device-1</code></pre></div>
<p>This should return a result of <code class="language-plaintext highlighter-rouge">201 Created</code> containing as response body of the created thing JSON.</p>
<p>In order to add more twins, we simply create additional devices via <a href="#register-a-new-device">“Register a new device”</a>
and add twins for them with the above snippet by simply adjusting the <em>device id</em> and <em>thing id</em> in the URL of both
HTTP requests.</p>
<h2 id="next-steps">Next Steps</h2>
<ul>
<li>Check out the <a href="https://www.eclipse.org/hono/docs/user-guide/">User Guides of Hono’s protocol adapters</a> to learn more about
the device protocols that are supported by Hono.</li>
<li>Learn about the <a href="https://www.eclipse.org/ditto/protocol-overview.html">Ditto Protocol</a> which is used to interact with the
digital twins that are maintained by Ditto.</li>
</ul>
<h2 id="updating-the-firmware">Updating the firmware</h2>
<p>tbd</p>
</div>
<div class="col-12 col-md-4 col-lg-3
">
<div class="position-sticky" style="top: 4rem;">
<aside>
<div class="card">
<div class="card-body">
<h5 class="card-title">Table of contents</h5>
<div id="toc" class="toc"></div>
</div>
</div>
</aside>
<script>generateToc("#toc", "h2[id], h3[id], h4[id]");</script>
</div>
</div>
</div>
</div>
</main>
<footer class="page-footer">
<div class="container">
<div class="row">
<div class="col-6 col-md">
<h5>Eclipse IoT Packages</h5>
<ul class="list-unstyled">
<li>
<a class="text-muted" href="/packages/">Home</a>
</li>
<li>
<a class="text-muted" href="/packages/about">About</a>
</li>
<li>
<a class="text-muted" href="/packages/contribute">Contribute</a>
</li>
<li>
<a class="text-muted" href="https://eclipse.org/security">Security</a>
</li>
</ul>
</div>
<div class="col-6 col-md">
<h5>Eclipse IoT</h5>
<ul class="list-unstyled">
<li>
<a class="text-muted" href="https://iot.eclipse.org">Top Level Project</a>
</li>
<li>
<a class="text-muted" href="https://www.eclipse.org/org/workinggroups/iotwg_charter.php">Working group</a>
</li>
</ul>
</div>
<div class="col-6 col-md">
<h5>Legal</h5>
<ul class="list-unstyled">
<li>
<a class="text-muted" href="https://www.eclipse.org/legal/privacy.php">Privacy Policy</a>
</li>
<li>
<a class="text-muted" href="https://www.eclipse.org/legal/termsofuse.php">Terms of Use</a>
</li>
<li>
<a class="text-muted" href="https://www.eclipse.org/legal/copyright.php">Copyright Agent</a>
</li>
<li>
<a class="text-muted" href="https://www.eclipse.org/legal/epl-2.0/">Eclipse Public License</a>
</li>
<li>
<a class="text-muted" href="https://www.eclipse.org/legal">Legal Resources</a>
</li>
</ul>
</div>
<div class="col-6 col-md">
<h5>Eclipse Foundation</h5>
<ul class="list-unstyled">
<li>
<a class="text-muted" href="https://eclipse.org/org">About us</a>
</li>
<li>
<a class="text-muted" href="https://www.eclipse.org/org/foundation/contact.php">Contact us</a>
</li>
<li>
<a class="text-muted" href="https://www.eclipse.org/org/foundation/directors.php">Board of Directors</a>
</li>
</ul>
</div>
</div>
<div class="row">
<div class="col-12 col-md text-muted">Copyright © Eclipse Foundation, Inc. All Rights Reserved.</div>
</div>
</div>
</footer>
<script src="/packages/assets/popper.min.js"></script>
<script src="/packages/assets/jquery.min.js"></script>
<script src="/packages/assets/bootstrap/bootstrap.min.js"></script>
<script src="/packages/assets/clipboard.min.js"></script>
<script src="/packages/assets/clipboard.js"></script>
</body>
</html>