<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Eclipse Ditto Blog</title>
        <description>Announcements, tutorials and examples around Eclipse Ditto and Digital Twins</description>
        <link>https://www.eclipse.dev/ditto/</link>
        <atom:link href="https://www.eclipse.dev/ditto/feed.xml" rel="self" type="application/rss+xml"/>
        <pubDate>Thu, 21 May 2026 16:06:19 +0000</pubDate>
        <lastBuildDate>Thu, 21 May 2026 16:06:19 +0000</lastBuildDate>
        <generator>Jekyll v4.3.4</generator>
        
        <item>
            <title>Announcing Eclipse Ditto Release 3.9.0</title>
            <description>&lt;p&gt;Eclipse Ditto team is excited to announce the availability of a new minor release, including new features:
Ditto &lt;a href=&quot;https://projects.eclipse.org/projects/iot.ditto/releases/3.9.0&quot;&gt;3.9.0&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The focus of this release is on &lt;strong&gt;policies, multi-tenancy and reuse&lt;/strong&gt;. Operating Ditto for several tenants
sharing one cluster — or for organizations that want to apply consistent governance and audit rules across
many policies — has historically required either duplicating policy entries across every tenant’s policy or
maintaining ad-hoc policy templates outside Ditto. Ditto 3.9.0 brings these patterns into the platform itself
with three complementary building blocks:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Namespace-scoped policy entries&lt;/strong&gt; let a single policy carry entries that only apply to Things in
specific namespaces — so a tenant’s policy can be expressed as a small set of namespace-aware rules
instead of as separate policies per tenant.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Namespace root policies&lt;/strong&gt; let operators configure policies that are transparently merged into every
policy of a given namespace, without each policy author having to opt in. This is the natural home for
cross-tenant concerns: governance and audit READ access, compliance monitoring, break-glass SRE accounts,
or forced minimum logging.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Entry-level &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;references&lt;/code&gt; for policies and policy imports&lt;/strong&gt; replace duplicated subject/resource blocks
with a uniform mechanism for additively merging from other entries — both inside the same policy and
from imported “template” policies. Imported entries can declare exactly what kinds of additions
(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;subjects&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;resources&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;namespaces&lt;/code&gt;) referencing entries are allowed to contribute via
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;allowedAdditions&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;transitiveImports&lt;/code&gt; opt selected imports in to multi-level resolution. The new
&lt;strong&gt;resolved policy view&lt;/strong&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;policy-view=resolved&lt;/code&gt;) returns the merged effective policy after imports and
namespace-root resolution, which makes debugging effective permissions much easier.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To round off the multi-tenancy story, &lt;strong&gt;gateway-level namespace access control&lt;/strong&gt; restricts which namespaces
an authenticated request may touch — for example by matching a JWT claim — so that a token issued for one
tenant cannot reach Things in another tenant’s namespace.&lt;/p&gt;

&lt;p&gt;Beyond policies, this release also brings a new &lt;strong&gt;WoT Discovery “Thing Directory” endpoint&lt;/strong&gt;, dynamically
&lt;strong&gt;scoping a WoT Thing Description to the requesting user’s permissions&lt;/strong&gt;, &lt;strong&gt;partial change notifications&lt;/strong&gt;
based on Policy READ permissions, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;checkPermissions&lt;/code&gt; API for &lt;strong&gt;all protocols&lt;/strong&gt; (WebSocket, AMQP, MQTT —
not only HTTP), &lt;strong&gt;encryption key rotation&lt;/strong&gt; for connection secrets, an &lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;empty()&lt;/code&gt; RQL filter&lt;/strong&gt;, the
&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fn:format()&lt;/code&gt; placeholder pipeline function&lt;/strong&gt;, &lt;strong&gt;slow search query logging&lt;/strong&gt;, &lt;strong&gt;configurable custom
MongoDB search indexes&lt;/strong&gt;, &lt;strong&gt;per-namespace activity-check configuration&lt;/strong&gt;, a &lt;strong&gt;history exploration mode&lt;/strong&gt; in
the Explorer UI and quite a number of further enhancements.&lt;/p&gt;

&lt;p&gt;On the operations side, Ditto now builds and runs on &lt;strong&gt;Java 25&lt;/strong&gt;, and the bundled Helm chart no longer
ships an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ingress-nginx&lt;/code&gt; controller — the choice of ingress controller is left to the operator. To reflect
this breaking change, the &lt;strong&gt;Helm chart moves to a major version &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;4.0.0&lt;/code&gt;&lt;/strong&gt;, and from now on the chart
follows its &lt;strong&gt;own semantic versioning&lt;/strong&gt;, decoupled from Ditto’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;appVersion&lt;/code&gt;. Chart-only changes will
increment the chart version independently of the Ditto release cycle.&lt;/p&gt;

&lt;h2 id=&quot;adoption&quot;&gt;Adoption&lt;/h2&gt;

&lt;p&gt;Companies are willing to show their adoption of Eclipse Ditto publicly:
&lt;a href=&quot;https://iot.eclipse.org/adopters/?#iot.ditto&quot;&gt;https://iot.eclipse.org/adopters/?#iot.ditto&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you use Eclipse Ditto it would be great to support the project by putting your logo there.&lt;/p&gt;

&lt;h2 id=&quot;changelog&quot;&gt;Changelog&lt;/h2&gt;

&lt;p&gt;The main improvements and additions of Ditto 3.9.0 are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Namespace-scoped policy entries&lt;/strong&gt; to limit a policy entry’s scope to a configured set of Thing namespaces&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Namespace root policies&lt;/strong&gt; which are transparently merged into all policies of a configured namespace&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Limiting&lt;/strong&gt; which &lt;strong&gt;namespaces&lt;/strong&gt; are accessible &lt;strong&gt;at the gateway level&lt;/strong&gt; via configurable, placeholder-based rules&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Entry-level &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;references&lt;/code&gt;&lt;/strong&gt; in policies and policy imports, with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;transitiveImports&lt;/code&gt; for selective multi-level resolution and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;allowedAdditions&lt;/code&gt; to control what may be merged in&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Resolved policy view&lt;/strong&gt; API option returning the merged effective policy after imports and namespace-root resolution&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Partial change notifications&lt;/strong&gt; based on Policy READ permissions&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;checkPermissions&lt;/code&gt; API for all protocols&lt;/strong&gt; — previously only HTTP — making permission checks available via WebSocket, AMQP and MQTT&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;WoT Discovery&lt;/strong&gt; “Thing Directory” endpoint following the W3C WoT Discovery specification&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Dynamically scoping a WoT Thing Description&lt;/strong&gt; to the requesting user’s policy permissions&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Encryption key rotation&lt;/strong&gt; for connectivity service secrets, including DevOps-triggered re-encryption of stored credentials&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;X509 client-certificate authentication&lt;/strong&gt; to MongoDB, with a configurable CA root certificate for the TLS connection&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;empty()&lt;/code&gt; RQL filter&lt;/strong&gt; to match absent or empty fields in search and event filters&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fn:format()&lt;/code&gt; placeholder pipeline function&lt;/strong&gt; for correlated field extraction from JSON arrays&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Slow search query logging&lt;/strong&gt; with configurable threshold to identify expensive queries&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Configurable custom MongoDB search indexes&lt;/strong&gt; for tuning Ditto search to specific workloads&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Per-namespace activity-check configuration&lt;/strong&gt; to vary entity passivation timeouts per namespace&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Live entities Prometheus metric&lt;/strong&gt; per namespace and entity type&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;OpenID Connect prerequisite-conditions&lt;/strong&gt; for early JWT rejection (e.g. audience validation)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Local/relative &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tm:ref&lt;/code&gt; references&lt;/strong&gt; in WoT ThingModel resolution&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ditto:deprecationNotice&lt;/code&gt;&lt;/strong&gt; WoT extension term to mark deprecated properties, actions and events&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;“Time Travel” mode&lt;/strong&gt; in the Explorer UI to inspect a Thing’s state at any past revision or timestamp, alongside live and historical event browsing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following non-functional work is also included:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Building and running Ditto with Java 25&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Optimizing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MongoReadJournal&lt;/code&gt; aggregation pipelines&lt;/strong&gt; and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ThingEventEnricher&lt;/code&gt; hot path&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;JFR-guided CPU optimisations&lt;/strong&gt; in the things, things-search, gateway and connectivity services&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Stackless 4xx exceptions&lt;/strong&gt; (feature-toggled) to eliminate stack-capture overhead on flow-control errors&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Configurable SSE publisher backpressure buffer size&lt;/strong&gt; to suppress noisy backpressure WARN logs from slow SSE consumers&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Comprehensive JavaDoc&lt;/strong&gt; for the public WoT model interfaces&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Helm chart bumped to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;4.0.0&lt;/code&gt;&lt;/strong&gt; with the bundled &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ingress-nginx&lt;/code&gt; controller &lt;strong&gt;removed&lt;/strong&gt; — operators provide their own ingress controller; the chart now uses its own semantic version, decoupled from Ditto’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;appVersion&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Updating dependencies to their latest versions&lt;/li&gt;
  &lt;li&gt;Providing &lt;strong&gt;additional configuration options&lt;/strong&gt; to &lt;strong&gt;Helm values&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following notable fixes are included:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Surfacing enforcement and validation errors for fire-and-forget commands&lt;/strong&gt; instead of silently swallowing them&lt;/li&gt;
  &lt;li&gt;Fixing &lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;checkPermissions&lt;/code&gt; ignoring permissions inherited from imported policies&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Fixing &lt;strong&gt;partial-access SSE event filtering&lt;/strong&gt; for subscribers with multiple authorization subjects&lt;/li&gt;
  &lt;li&gt;Fixing a &lt;strong&gt;MongoDB aggregation pipeline performance regression&lt;/strong&gt; affecting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;connections_journal&lt;/code&gt; reads&lt;/li&gt;
  &lt;li&gt;Fixing a &lt;strong&gt;Kafka consumer crash loop&lt;/strong&gt; triggered by messages with blank header values&lt;/li&gt;
  &lt;li&gt;Fixing a &lt;strong&gt;Fluency thread leak&lt;/strong&gt; in the connection logger publisher&lt;/li&gt;
  &lt;li&gt;Fixing &lt;strong&gt;subscription handling for multiple topics combined with extra fields&lt;/strong&gt; in connectivity outbound mapping&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Redacting sensitive header values&lt;/strong&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DittoHeaders.toString()&lt;/code&gt; to prevent accidental log leaks&lt;/li&gt;
  &lt;li&gt;Converting transient &lt;strong&gt;enforcement &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AskTimeoutException&lt;/code&gt; to HTTP 503&lt;/strong&gt; instead of 500 during rolling restarts, so clients see a retryable error&lt;/li&gt;
  &lt;li&gt;Fixing &lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ssl-config&lt;/code&gt; not being picked up&lt;/strong&gt; for self-signed certificates against the OpenID Connect issuer&lt;/li&gt;
  &lt;li&gt;Closing a &lt;strong&gt;shadowing vulnerability in namespace-policies&lt;/strong&gt; by routing namespace-policy entries through rewritten labels&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please have a look at the &lt;a href=&quot;release_notes_390.html&quot;&gt;3.9.0 release notes&lt;/a&gt; for more detailed information on the release.&lt;/p&gt;

&lt;h2 id=&quot;artifacts&quot;&gt;Artifacts&lt;/h2&gt;

&lt;p&gt;The new Java artifacts have been published at the &lt;a href=&quot;https://repo.eclipse.org/content/repositories/ditto/&quot;&gt;Eclipse Maven repository&lt;/a&gt;
as well as &lt;a href=&quot;https://repo1.maven.org/maven2/org/eclipse/ditto/&quot;&gt;Maven central&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The Ditto JavaScript client release was published on &lt;a href=&quot;https://www.npmjs.com/~eclipse_ditto&quot;&gt;npmjs.com&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/@eclipse-ditto/ditto-javascript-client-dom&quot;&gt;@eclipse-ditto/ditto-javascript-client-dom&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/@eclipse-ditto/ditto-javascript-client-node&quot;&gt;@eclipse-ditto/ditto-javascript-client-node&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Docker images have been pushed to Docker Hub:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-policies/&quot;&gt;eclipse/ditto-policies&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-things/&quot;&gt;eclipse/ditto-things&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-things-search/&quot;&gt;eclipse/ditto-things-search&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-gateway/&quot;&gt;eclipse/ditto-gateway&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-connectivity/&quot;&gt;eclipse/ditto-connectivity&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Ditto Helm chart has been published to Docker Hub:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto/&quot;&gt;eclipse/ditto&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;figure&gt;&lt;img class=&quot;docimage&quot; src=&quot;images/ditto.svg&quot; alt=&quot;Ditto&quot; style=&quot;max-width: 500px&quot; /&gt;&lt;/figure&gt;

&lt;p&gt;–&lt;br /&gt;
The Eclipse Ditto team&lt;/p&gt;
</description>
            <pubDate>Wed, 13 May 2026 00:00:00 +0000</pubDate>
            <link>https://www.eclipse.dev/ditto/2026-05-13-release-announcement-390.html</link>
            <guid isPermaLink="true">https://www.eclipse.dev/ditto/2026-05-13-release-announcement-390.html</guid>
            
            <category>blog</category>
            
            
        </item>
        
        <item>
            <title>Helm chart now ingress controller agnostic</title>
            <description>&lt;p&gt;Starting with Helm chart version 4.0.0, Eclipse Ditto’s Kubernetes deployment is no longer tied to a specific ingress
controller. The chart now provides clean, standard Kubernetes Ingress resources that work with &lt;strong&gt;any&lt;/strong&gt; ingress controller
— whether you use ingress-nginx, Traefik, HAProxy, Kong, or any other implementation.&lt;/p&gt;

&lt;h2 id=&quot;what-changed&quot;&gt;What changed&lt;/h2&gt;

&lt;p&gt;Previously, the Ditto Helm chart bundled an entire &lt;strong&gt;ingress-nginx controller deployment&lt;/strong&gt; (854 lines of RBAC,
Deployments, Services, admission webhooks, and IngressClass) and hardcoded &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nginx.ingress.kubernetes.io/*&lt;/code&gt; annotations
across all Ingress resource templates. This forced users to use ingress-nginx and prevented adoption of other ingress
controllers.&lt;/p&gt;

&lt;p&gt;In version 4.0.0, we made the following changes:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Removed&lt;/strong&gt; the bundled ingress-nginx controller deployment — users bring their own ingress controller&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Removed&lt;/strong&gt; all nginx-specific annotations from Ingress resources — annotations are now empty by default&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Simplified&lt;/strong&gt; path types to standard &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Prefix&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Exact&lt;/code&gt; — no more controller-specific regex paths&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Added&lt;/strong&gt; per-group &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enabled&lt;/code&gt; flags — each route group (api, ws, ui, devops) can be independently toggled&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Replaced&lt;/strong&gt; the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;backendSuffix&lt;/code&gt; pattern with explicit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;service.name&lt;/code&gt; references&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;breaking-changes&quot;&gt;Breaking changes&lt;/h2&gt;

&lt;p&gt;This is a &lt;strong&gt;major version bump&lt;/strong&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3.x&lt;/code&gt; → &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;4.0.0&lt;/code&gt;) with breaking changes to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;values.yaml&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ingress.controller.*&lt;/code&gt; — entire block removed (no longer deploying a controller)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ingress.annotations&lt;/code&gt; — global nginx-specific annotations removed&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ingress.api.kubernetesAuthAnnotations&lt;/code&gt; — removed&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ingress.className&lt;/code&gt; — default changed from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;nginx&quot;&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;&quot;&lt;/code&gt; (empty)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ingress.host&lt;/code&gt; — default changed from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;localhost&quot;&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;&quot;&lt;/code&gt; (catch-all)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;backendSuffix&lt;/code&gt; — replaced by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;service.name&lt;/code&gt; in each path entry&lt;/li&gt;
  &lt;li&gt;All per-group nginx-specific annotation blocks — removed&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;new-valuesyaml-structure&quot;&gt;New values.yaml structure&lt;/h2&gt;

&lt;p&gt;The ingress section is now clean and controller-agnostic:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;ingress&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# Set to your controller&apos;s IngressClass&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;             &lt;span class=&quot;c1&quot;&gt;# Optional hostname — if empty, no host rule (catch-all)&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;tls&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[]&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;api&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;annotations&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;{}&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# Add your controller-specific annotations here&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;paths&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/api&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;pathType&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Prefix&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;gateway&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/stats&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;pathType&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Prefix&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;gateway&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/overall&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;pathType&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Prefix&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;gateway&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;ws&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;annotations&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;{}&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;paths&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/ws&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;pathType&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Prefix&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;gateway&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;ui&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;annotations&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;{}&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# defaultBackend serves as the catch-all for unmatched paths (e.g. the landing page)&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;defaultBackend&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;nginx&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;paths&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;pathType&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Exact&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;nginx&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/apidoc&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;pathType&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Prefix&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;swaggerui&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/ui&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;pathType&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Prefix&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;dittoui&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;devops&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;annotations&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;{}&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;paths&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/devops&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;pathType&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Prefix&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;gateway&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/health&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;pathType&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Prefix&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;gateway&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/status&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;pathType&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Prefix&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;gateway&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/api/2/connections&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;pathType&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Prefix&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;gateway&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;deployment-modes&quot;&gt;Deployment modes&lt;/h2&gt;

&lt;p&gt;The chart supports three deployment modes:&lt;/p&gt;

&lt;h3 id=&quot;standalone-nginx-pod-default-unchanged&quot;&gt;Standalone nginx pod (default, unchanged)&lt;/h3&gt;

&lt;p&gt;The standalone nginx reverse proxy remains the default for local and development setups.
No ingress controller needed — access Ditto via port-forward:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;helm &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;ditto ditto/ditto
kubectl port-forward svc/ditto-nginx 8080:8080
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;ingress-with-nginx-pod&quot;&gt;Ingress with nginx pod&lt;/h3&gt;

&lt;p&gt;Use Ingress resources for external access while keeping the nginx pod for the landing page and static resources:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;helm &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;ditto ditto/ditto &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;--set&lt;/span&gt; ingress.enabled&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;--set&lt;/span&gt; ingress.className&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;nginx &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;--set&lt;/span&gt; ingress.host&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;ditto.example.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;ingress-only-no-nginx-pod&quot;&gt;Ingress only (no nginx pod)&lt;/h3&gt;

&lt;p&gt;For production setups where the landing page is not needed, disable the nginx pod and the UI ingress’s root path:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;helm &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;ditto ditto/ditto &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;--set&lt;/span&gt; ingress.enabled&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;--set&lt;/span&gt; ingress.className&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;nginx &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;--set&lt;/span&gt; ingress.host&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;ditto.example.com &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;--set&lt;/span&gt; nginx.enabled&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;controller-specific-configuration&quot;&gt;Controller-specific configuration&lt;/h2&gt;

&lt;p&gt;Since controller-specific behavior (authentication, CORS, timeouts, URL rewriting) is now the user’s responsibility,
here are examples for common ingress controllers.&lt;/p&gt;

&lt;h3 id=&quot;ingress-nginx&quot;&gt;ingress-nginx&lt;/h3&gt;

&lt;p&gt;For the Ditto UI and Swagger API docs, ingress-nginx requires regex paths and a rewrite annotation to strip the
path prefix before forwarding to the backend.&lt;/p&gt;

&lt;p&gt;Note that when &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;use-regex&lt;/code&gt; is enabled, the root path &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/&lt;/code&gt; must be specified as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/$&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pathType: ImplementationSpecific&lt;/code&gt;
to ensure it matches only the exact root path and does not conflict with the ingress controller’s default catch-all:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;ingress&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;nginx&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ditto.example.com&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;api&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;annotations&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;nginx.ingress.kubernetes.io/proxy-read-timeout&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;70&quot;&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;nginx.ingress.kubernetes.io/proxy-send-timeout&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;70&quot;&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;ws&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;annotations&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;nginx.ingress.kubernetes.io/proxy-read-timeout&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;86400&quot;&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;nginx.ingress.kubernetes.io/proxy-send-timeout&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;86400&quot;&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;nginx.ingress.kubernetes.io/proxy-buffering&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;off&quot;&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;ui&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;annotations&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;nginx.ingress.kubernetes.io/use-regex&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;true&quot;&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;nginx.ingress.kubernetes.io/rewrite-target&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/$2&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;paths&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/$&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;pathType&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ImplementationSpecific&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;nginx&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/apidoc(/|$)(.*)&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;pathType&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ImplementationSpecific&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;swaggerui&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/ui(/|$)(.*)&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;pathType&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ImplementationSpecific&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;dittoui&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;traefik&quot;&gt;Traefik&lt;/h3&gt;

&lt;p&gt;Traefik requires a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Middleware&lt;/code&gt; CRD to strip path prefixes. First, create the middleware in the Ditto namespace:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;traefik.io/v1alpha1&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Middleware&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;strip-prefix&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ditto&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;stripPrefix&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;prefixes&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/ui&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/apidoc&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then reference it in the ingress configuration:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;ingress&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;traefik&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ditto.example.com&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;ui&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;annotations&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;traefik.ingress.kubernetes.io/router.middlewares&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ditto-strip-prefix@kubernetescrd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;haproxy&quot;&gt;HAProxy&lt;/h3&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;ingress&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;haproxy&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ditto.example.com&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;ui&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;annotations&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;haproxy.org/path-rewrite&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;/&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;what-stays-the-same&quot;&gt;What stays the same&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;The &lt;strong&gt;standalone nginx pod&lt;/strong&gt; for local/development deployments is unchanged&lt;/li&gt;
  &lt;li&gt;The &lt;strong&gt;OpenShift Route&lt;/strong&gt; template is unchanged&lt;/li&gt;
  &lt;li&gt;All &lt;strong&gt;Ditto service templates&lt;/strong&gt; (gateway, things, policies, connectivity, etc.) are unchanged&lt;/li&gt;
  &lt;li&gt;The &lt;strong&gt;4 route groups&lt;/strong&gt; (api, ws, ui, devops) cover all Ditto endpoints — the root landing page is now part of the ui group&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;migrating-from-3x&quot;&gt;Migrating from 3.x&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Install your ingress controller separately&lt;/strong&gt; (e.g., via its own Helm chart)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Update your values.yaml&lt;/strong&gt; to match the new structure — replace &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;backendSuffix&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;service.name&lt;/code&gt;,
remove &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ingress.controller.*&lt;/code&gt; and global annotations&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Add controller-specific annotations&lt;/strong&gt; to the appropriate route groups&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Upgrade the chart&lt;/strong&gt; to version 4.0.0&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;figure&gt;&lt;img class=&quot;docimage&quot; src=&quot;images/ditto.svg&quot; alt=&quot;Ditto&quot; style=&quot;max-width: 500px&quot; /&gt;&lt;/figure&gt;

&lt;p&gt;–&lt;br /&gt;
The Eclipse Ditto team&lt;/p&gt;
</description>
            <pubDate>Wed, 13 May 2026 00:00:00 +0000</pubDate>
            <link>https://www.eclipse.dev/ditto/2026-05-13-ingress-controller-agnostic-helm-chart.html</link>
            <guid isPermaLink="true">https://www.eclipse.dev/ditto/2026-05-13-ingress-controller-agnostic-helm-chart.html</guid>
            
            <category>blog</category>
            
            <category>kubernetes</category>
            
            <category>helm</category>
            
            
        </item>
        
        <item>
            <title>WoT Tooling: Code Generation and OpenAPI from Thing Models</title>
            <description>&lt;p&gt;Eclipse Ditto’s &lt;a href=&quot;2022-03-03-wot-integration.html&quot;&gt;W3C WoT (Web of Things) integration&lt;/a&gt; lets you reference Thing Models in &lt;a href=&quot;basic-thing.html#definition&quot;&gt;Thing Definitions&lt;/a&gt;, 
generate &lt;a href=&quot;basic-wot-integration.html&quot;&gt;Thing Descriptions&lt;/a&gt;, and create Thing skeletons at runtime. 
Alongside that, the &lt;strong&gt;&lt;a href=&quot;https://github.com/eclipse-ditto/ditto-wot-tooling&quot;&gt;ditto-wot-tooling&lt;/a&gt;&lt;/strong&gt; project provides build-time 
and CLI tools to generate &lt;strong&gt;Kotlin code&lt;/strong&gt; and &lt;strong&gt;OpenAPI specifications&lt;/strong&gt; from the same WoT Thing Models.&lt;/p&gt;

&lt;p&gt;This post gives an overview of the available tools, their configuration, and some best practices so the Ditto community can use them effectively.&lt;/p&gt;

&lt;h2 id=&quot;overview-of-ditto-wot-tooling&quot;&gt;Overview of ditto-wot-tooling&lt;/h2&gt;

&lt;p&gt;The &lt;a href=&quot;https://github.com/eclipse-ditto/ditto-wot-tooling&quot;&gt;ditto-wot-tooling&lt;/a&gt; repository hosts two main tools:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Tool&lt;/th&gt;
      &lt;th&gt;Purpose&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;WoT Kotlin Generator&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Maven plugin that downloads a WoT Thing Model (JSON-LD) via HTTP and generates Kotlin data classes and path helpers for type-safe use in your application.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;WoT to OpenAPI Generator&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Converts WoT Thing Models into &lt;strong&gt;OpenAPI 3.1.0&lt;/strong&gt; specifications that describe Ditto’s HTTP API for Things conforming to that model. Usable as CLI or library.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Both tools consume Thing Models from a URL (e.g. a deployed model registry). They complement Ditto’s runtime WoT support: 
Ditto fetches Thing Models (TMs) to build skeletons and Thing Descriptions; the tooling uses the same TMs at build time or in CI to generate client code and API docs.&lt;/p&gt;

&lt;h2 id=&quot;wot-kotlin-generator-maven-plugin&quot;&gt;WoT Kotlin Generator Maven plugin&lt;/h2&gt;

&lt;p&gt;The WoT Kotlin Generator produces Kotlin code (data classes, builders, path DSL) from a single Thing Model URL. The generated code aligns with Ditto’s API and can be used to build merge commands, RQL filters, and path references in a type-safe way.&lt;/p&gt;

&lt;h3 id=&quot;why-use-generated-models&quot;&gt;Why use generated models?&lt;/h3&gt;

&lt;p&gt;Using the Kotlin generator gives you a &lt;strong&gt;single source of truth&lt;/strong&gt;: your backend models are derived directly from the WoT Thing Models, which act as the schema for your Things. Ditto supports &lt;a href=&quot;basic-wot-integration.html&quot;&gt;WoT-based validation&lt;/a&gt; of Things and Features against the referenced Thing Model. If you maintain models by hand, they can drift from the WoT schema and become incompatible—leading to validation errors at runtime, failed updates, or subtle bugs. Generated models stay in sync with the Thing Model you point the plugin at, so the payloads you build are valid by construction. That makes development easier, safer, and more predictable: you get compile-time safety and alignment with Ditto’s validation instead of discovering mismatches only when Ditto rejects a request.&lt;/p&gt;

&lt;h3 id=&quot;maven-setup&quot;&gt;Maven setup&lt;/h3&gt;

&lt;p&gt;Add the &lt;strong&gt;common-models&lt;/strong&gt; dependency (required by the generated code) and the plugin to your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pom.xml&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.eclipse.ditto&lt;span class=&quot;nt&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;wot-kotlin-generator-common-models&lt;span class=&quot;nt&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0.0&lt;span class=&quot;nt&quot;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.eclipse.ditto&lt;span class=&quot;nt&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;wot-kotlin-generator-maven-plugin&lt;span class=&quot;nt&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0.0&lt;span class=&quot;nt&quot;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;id&amp;gt;&lt;/span&gt;code-generator-my-model&lt;span class=&quot;nt&quot;&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;phase&amp;gt;&lt;/span&gt;generate-sources&lt;span class=&quot;nt&quot;&gt;&amp;lt;/phase&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;codegen&lt;span class=&quot;nt&quot;&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;thingModelUrl&amp;gt;&lt;/span&gt;${modelBaseUrl}/my-domain/my-model-${my-model.version}.tm.jsonld&lt;span class=&quot;nt&quot;&gt;&amp;lt;/thingModelUrl&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;packageName&amp;gt;&lt;/span&gt;com.example.wot.model.mymodel&lt;span class=&quot;nt&quot;&gt;&amp;lt;/packageName&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;classNamingStrategy&amp;gt;&lt;/span&gt;ORIGINAL_THEN_COMPOUND&lt;span class=&quot;nt&quot;&gt;&amp;lt;/classNamingStrategy&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/executions&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;full-plugin-configuration-options&quot;&gt;Full plugin configuration options&lt;/h3&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Parameter&lt;/th&gt;
      &lt;th&gt;Type&lt;/th&gt;
      &lt;th&gt;Required&lt;/th&gt;
      &lt;th&gt;Default&lt;/th&gt;
      &lt;th&gt;Description&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;thingModelUrl&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;String&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;-&lt;/td&gt;
      &lt;td&gt;Full HTTP(S) URL of the WoT Thing Model (JSON-LD). The plugin downloads it at build time.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;packageName&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;String&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;org.eclipse.ditto.wot.kotlin.generator.model&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Target package for generated Kotlin classes.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;outputDir&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;String&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;target/generated-sources&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Directory where generated sources are written (Maven adds it as a source root).&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enumGenerationStrategy&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;String&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;INLINE&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;How to generate enums: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;INLINE&lt;/code&gt; (nested in the class that uses them) or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SEPARATE_CLASS&lt;/code&gt; (standalone enum classes).&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;classNamingStrategy&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;String&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;COMPOUND_ALL&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;How to name generated classes: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;COMPOUND_ALL&lt;/code&gt; (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RoomAttributes&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BatteryProperties&lt;/code&gt;) or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ORIGINAL_THEN_COMPOUND&lt;/code&gt; (use schema title when possible, compound only on conflict).&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;generateSuspendDsl&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;boolean&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;false&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;true&lt;/code&gt;, generated DSL builder functions are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;suspend&lt;/code&gt; functions for Kotlin coroutines.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Use Maven properties for the base URL and model version so you can switch environments and pin versions in one place:&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;properties&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;modelBaseUrl&amp;gt;&lt;/span&gt;https://models.example.com&lt;span class=&quot;nt&quot;&gt;&amp;lt;/modelBaseUrl&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;my-model.version&amp;gt;&lt;/span&gt;1.0.0&lt;span class=&quot;nt&quot;&gt;&amp;lt;/my-model.version&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;enum-and-class-naming-strategies&quot;&gt;Enum and class naming strategies&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Enum generation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;INLINE&lt;/code&gt;&lt;/strong&gt; (default): Enums are nested inside the class that uses them (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Thermostat.ThermostatStatus&lt;/code&gt;). Keeps the number of files lower and is convenient for simple enums.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SEPARATE_CLASS&lt;/code&gt;&lt;/strong&gt;: Enums are generated as standalone classes in separate files. Better for IDE navigation and reuse across multiple classes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Class naming&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;COMPOUND_ALL&lt;/code&gt;&lt;/strong&gt; (default): Class names always combine parent and child (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SmartheatingThermostat&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RoomAttributes&lt;/code&gt;). Guarantees unique names and makes hierarchy clear.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ORIGINAL_THEN_COMPOUND&lt;/code&gt;&lt;/strong&gt;: Uses the schema &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;title&lt;/code&gt; when there is no conflict (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Thermostat&lt;/code&gt;); falls back to compound names (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SmartheatingThermostat&lt;/code&gt;) when needed. Produces shorter, more readable names when possible.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;dsl-regular-vs-suspend&quot;&gt;DSL: regular vs suspend&lt;/h3&gt;

&lt;p&gt;By default, the plugin generates regular Kotlin DSL functions for building thing/feature/property objects. Set &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;generateSuspendDsl=true&lt;/code&gt; to generate &lt;strong&gt;suspend&lt;/strong&gt; DSL functions instead, so you can use them inside coroutines and call suspend code from within the DSL block.&lt;/p&gt;

&lt;h3 id=&quot;generated-code-structure&quot;&gt;Generated code structure&lt;/h3&gt;

&lt;p&gt;The plugin generates a package structure aligned with your Thing Model:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Main thing class&lt;/strong&gt; – root class for the thing (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FloorLamp&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Device&lt;/code&gt;).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;attributes/&lt;/code&gt;&lt;/strong&gt; – interfaces/classes for thing-level attributes (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Location&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Room&lt;/code&gt;).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;features/&lt;/code&gt;&lt;/strong&gt; – one subpackage per feature with feature and property types (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lamp/Lamp.kt&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LampProperties.kt&lt;/code&gt;).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;DSL functions&lt;/strong&gt; – fluent builders (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;floorLamp { ... }&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;features { lamp { ... } }&lt;/code&gt;).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Path and RQL helpers&lt;/strong&gt; – provided by the &lt;strong&gt;common-models&lt;/strong&gt; dependency; the generated code uses them for type-safe paths and &lt;a href=&quot;basic-rql.html&quot;&gt;RQL&lt;/a&gt; expressions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You must add the &lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wot-kotlin-generator-common-models&lt;/code&gt;&lt;/strong&gt; dependency to your project; the generated code extends interfaces and uses path builders from that artifact.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the generator supports&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The plugin follows the WoT Thing Model specification: it handles &lt;strong&gt;properties&lt;/strong&gt; (read/write, various types), &lt;strong&gt;actions&lt;/strong&gt; (with input/output schemas), &lt;strong&gt;events&lt;/strong&gt;, and &lt;strong&gt;links&lt;/strong&gt; (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tm:extends&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tm:submodel&lt;/code&gt;). Supported data types include primitives (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;number&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;integer&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;boolean&lt;/code&gt;), &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;object&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;array&lt;/code&gt;, and custom types via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$ref&lt;/code&gt;. Enums in the schema become Kotlin enums according to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enumGenerationStrategy&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;best-practices&quot;&gt;Best practices&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Pin model versions&lt;/strong&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pom.xml&lt;/code&gt; (or a BOM) so builds are reproducible and you can upgrade TMs in a controlled way.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;One execution per “logical” model&lt;/strong&gt;: use a separate &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;execution&amp;gt;&lt;/code&gt; for each Thing Model you need (e.g. device, room, building). Each execution has its own &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;thingModelUrl&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;packageName&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Align with runtime definitions&lt;/strong&gt;: use the same base URL and versioning as the &lt;a href=&quot;basic-thing.html#definition&quot;&gt;Thing Definition&lt;/a&gt; URLs you send to Ditto, so the generated types match what Ditto expects.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Add the common-models dependency&lt;/strong&gt;: the generated code depends on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wot-kotlin-generator-common-models&lt;/code&gt; for path building and Ditto RQL helpers; do not omit it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;running-the-plugin-from-the-command-line&quot;&gt;Running the plugin from the command line&lt;/h3&gt;

&lt;p&gt;You can invoke the plugin directly without a full POM execution by passing parameters with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-D&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mvn org.eclipse.ditto:wot-kotlin-generator-maven-plugin:codegen &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;-DthingModelUrl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;https://models.example.com/device-1.0.0.tm.jsonld &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;-DpackageName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;com.example.wot.model.device &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;-DoutputDir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;target/generated-sources &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;-DenumGenerationStrategy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;SEPARATE_CLASS &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;-DclassNamingStrategy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;ORIGINAL_THEN_COMPOUND
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Optional: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-DgenerateSuspendDsl=true&lt;/code&gt; for suspend DSL. Useful for one-off generation or scripts.&lt;/p&gt;

&lt;h3 id=&quot;path-generation-and-type-safe-rql&quot;&gt;Path generation and type-safe RQL&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;common-models&lt;/strong&gt; dependency provides a path builder API that works with the generated classes. You get compile-time–safe paths and &lt;a href=&quot;basic-rql.html&quot;&gt;RQL&lt;/a&gt; expressions instead of string concatenation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Path builder API&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pathBuilder().from(start = SomeClass::property)&lt;/code&gt;&lt;/strong&gt; – start a path from a property (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Thing::features&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Device::attributes&lt;/code&gt;).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.add(NextClass::property)&lt;/code&gt;&lt;/strong&gt; – append path segments (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Features::thermostat&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Attributes::location&lt;/code&gt;).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.build()&lt;/code&gt;&lt;/strong&gt; – finalize as a path string (e.g. for logging or custom use).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.buildSearchProperty()&lt;/code&gt;&lt;/strong&gt; – create a search property object for RQL comparisons (see below).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.buildJsonPointer()&lt;/code&gt;&lt;/strong&gt; – build a Ditto JSON Pointer (e.g. for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MergeThing&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DeleteAttribute&lt;/code&gt;). Useful when the generated model exposes a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;startPath&lt;/code&gt; (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Location::startPath&lt;/code&gt;) for a nested type.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;RQL combinators&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use these from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DittoRql.Companion&lt;/code&gt; to combine conditions:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;and(condition1, condition2, ...)&lt;/code&gt;&lt;/strong&gt; – all conditions must hold.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;or(condition1, condition2, ...)&lt;/code&gt;&lt;/strong&gt; – at least one condition must hold.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;not(condition)&lt;/code&gt;&lt;/strong&gt; – negate a condition.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each condition is often a search property expression (see below). Call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.toString()&lt;/code&gt; on the result to get the RQL string for Ditto’s search API or conditional request headers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Search property methods&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.buildSearchProperty()&lt;/code&gt; you can chain one of:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Method&lt;/th&gt;
      &lt;th&gt;RQL&lt;/th&gt;
      &lt;th&gt;Example&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exists()&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;property exists&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.exists()&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eq(value)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;equals&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.eq(&quot;THERMOSTAT&quot;)&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ne(value)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;not equal&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.ne(0)&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gt(value)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;greater than&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.gt(20.0)&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ge(value)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;greater or equal&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.ge(timestamp)&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lt(value)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;less than&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.lt(timestamp)&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;le(value)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;less or equal&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.le(&quot;2026-02-20T08:00:00Z&quot;)&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;like(pattern)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;wildcard &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;?&lt;/code&gt; / &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.like(&quot;room-*&quot;)&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ilike(pattern)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;case-insensitive like&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.ilike(&quot;*sensor*&quot;)&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;in(values)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;value in collection&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.in(listOf(&quot;A&quot;, &quot;B&quot;))&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;strong&gt;Example: conditional merge (RQL for Ditto headers)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Typical use is building a condition for Ditto’s &lt;a href=&quot;basic-conditional-requests.html&quot;&gt;conditional request&lt;/a&gt; header (e.g. for merge or delete). 
Below, we require that the thing has a given attribute type and either no &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mountedOn&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mountedOn&lt;/code&gt; less than or equal to a timestamp:&lt;/p&gt;

&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;com.example.wot.model.path.DittoRql.Companion.and&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;com.example.wot.model.path.DittoRql.Companion.or&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;com.example.wot.model.path.DittoRql.Companion.not&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;com.example.wot.model.path.DittoRql.Companion.pathBuilder&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Condition: type eq &quot;THERMOSTAT&quot; AND&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//   (NOT exists(location/mountedOn) OR location/mountedOn &amp;lt;= eventDate)&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;updateCondition&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;and&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;pathBuilder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Device&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Attributes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;buildSearchProperty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;eq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;THERMOSTAT&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;or&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;not&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;nf&quot;&gt;pathBuilder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Device&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Attributes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Location&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mountedOn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;buildSearchProperty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;pathBuilder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Device&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Attributes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Location&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mountedOn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;buildSearchProperty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;le&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eventDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Use in Ditto merge headers&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;mergeCmd&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MergeThing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;withThing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;thingId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;thing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;dittoHeaders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;toBuilder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;condition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;updateCondition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Example: JSON pointer for DeleteAttribute&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For commands that take a JSON pointer (e.g. delete a nested attribute), use the generated &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;startPath&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;buildJsonPointer()&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;deleteLocationAttribute&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DeleteAttribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;thingId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;pathBuilder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Location&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;startPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;buildJsonPointer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;dittoHeaders&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Example: RQL for search&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The same RQL string can be passed to Ditto’s &lt;a href=&quot;basic-search.html&quot;&gt;search API&lt;/a&gt; (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GET /search/things?filter=...&lt;/code&gt;):&lt;/p&gt;

&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;filter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;pathBuilder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Device&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Attributes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;buildSearchProperty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;dittoClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;searchThings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The exact property names and types (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Device&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Attributes&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Location&lt;/code&gt;, etc.) come from your Thing Model; the generator produces the matching classes and path helpers so that paths and RQL stay in sync with the model.&lt;/p&gt;

&lt;h2 id=&quot;wot-to-openapi-generator&quot;&gt;WoT to OpenAPI Generator&lt;/h2&gt;

&lt;p&gt;The WoT to OpenAPI Generator turns a WoT Thing Model into an &lt;strong&gt;OpenAPI 3.1.0&lt;/strong&gt; YAML (or JSON) that describes Ditto’s HTTP API for Things that follow that model: thing and attribute paths, feature properties, and actions (e.g. inbox messages).&lt;/p&gt;

&lt;h3 id=&quot;benefits-for-frontends-and-api-consumers&quot;&gt;Benefits for frontends and API consumers&lt;/h3&gt;

&lt;p&gt;The generated OpenAPI spec is a standard, tool-friendly contract. 
Frontend teams can feed it into code generators (e.g. OpenAPI Generator, Orval, or the OpenAPI TypeScript/JavaScript generators) to &lt;strong&gt;generate TypeScript or JavaScript models&lt;/strong&gt;, &lt;strong&gt;typed HTTP client methods&lt;/strong&gt;, and &lt;strong&gt;request/response types&lt;/strong&gt; for thing, attribute, feature, and action endpoints. 
That keeps the UI in sync with the backend: API changes are reflected in the spec, and regenerating client code updates types and calls in one step. 
You get autocomplete, fewer manual typos, and consistent request shapes. The same spec can drive API documentation (e.g. Swagger UI or Redoc), integration tests, or other clients (mobile, scripts). 
One Thing Model (TM) thus drives both backend Kotlin models and frontend API usage from a single source of truth.&lt;/p&gt;

&lt;h3 id=&quot;usage&quot;&gt;Usage&lt;/h3&gt;

&lt;p&gt;The generator is available as a &lt;strong&gt;CLI&lt;/strong&gt; (run with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;java -jar&lt;/code&gt;) or as a &lt;strong&gt;library&lt;/strong&gt;. You can get the JAR from &lt;a href=&quot;https://search.maven.org/artifact/org.eclipse.ditto/wot-to-openapi-generator&quot;&gt;Maven Central&lt;/a&gt; or build from &lt;a href=&quot;https://github.com/eclipse-ditto/ditto-wot-tooling/tree/main/wot-to-openapi-generator&quot;&gt;source&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Command-line:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;java &lt;span class=&quot;nt&quot;&gt;-jar&lt;/span&gt; wot-to-openapi-generator-1.0.0.jar &amp;lt;model-base-url&amp;gt; &amp;lt;model-name&amp;gt; &amp;lt;model-version&amp;gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;ditto-base-url]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Argument&lt;/th&gt;
      &lt;th&gt;Description&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;model-base-url&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Base URL where the TM is served (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;https://models.example.com&lt;/code&gt;).&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;model-name&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Model name (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dimmable-colored-lamp&lt;/code&gt;). The generator will load &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{model-base-url}/{model-name}-{model-version}.tm.jsonld&lt;/code&gt;.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;model-version&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Version (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1.0.0&lt;/code&gt;).&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ditto-base-url&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;(Optional) Base URL of the Ditto API (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;https://ditto.example.com/api/2/things&lt;/code&gt;). Used in the generated &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;servers&lt;/code&gt; section.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;java &lt;span class=&quot;nt&quot;&gt;-jar&lt;/span&gt; wot-to-openapi-generator-1.0.0.jar &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  https://eclipse-ditto.github.io/ditto-examples/wot/models/ &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  dimmable-colored-lamp &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  1.0.0 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  https://ditto.example.com/api/2/things
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Generated specs are written under a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;generated/&lt;/code&gt; directory (path may vary by version). The output includes thing-level and attribute-level endpoints, feature properties, and action endpoints with request/response schemas derived from the TM.&lt;/p&gt;

&lt;h3 id=&quot;best-practices-1&quot;&gt;Best practices&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Run in CI&lt;/strong&gt;: generate OpenAPI from your main Thing Models in your pipeline and publish the artifacts (e.g. to a docs site or S3) so API consumers always see up-to-date specs.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Use the same model base URL and versions&lt;/strong&gt; as in your Kotlin generator and Ditto Thing definitions, so docs and code stay in sync.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Set &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ditto-base-url&lt;/code&gt;&lt;/strong&gt; when you want the generated &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;servers&lt;/code&gt; section to point at your Ditto instance; otherwise the generator may use a default.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;ditto-wot-tooling&lt;/strong&gt; provides the &lt;strong&gt;WoT Kotlin Generator&lt;/strong&gt; (Maven plugin) and the &lt;strong&gt;WoT to OpenAPI Generator&lt;/strong&gt; (CLI/library). Both take a WoT Thing Model URL and produce artifacts you can use at build time or in CI.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;WoT Kotlin Generator&lt;/strong&gt;: configure &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;thingModelUrl&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;packageName&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;outputDir&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enumGenerationStrategy&lt;/code&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;INLINE&lt;/code&gt; / &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SEPARATE_CLASS&lt;/code&gt;), &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;classNamingStrategy&lt;/code&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;COMPOUND_ALL&lt;/code&gt; / &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ORIGINAL_THEN_COMPOUND&lt;/code&gt;), and optionally &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;generateSuspendDsl&lt;/code&gt;; pin model versions; add one execution per model; depend on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wot-kotlin-generator-common-models&lt;/code&gt;. The generated code plus common-models give you type-safe path building (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pathBuilder().from().add().buildSearchProperty()&lt;/code&gt;) and RQL combinators (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;and&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;or&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;not&lt;/code&gt;) and comparison methods (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exists&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eq&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gt&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lt&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;like&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;in&lt;/code&gt;, etc.) for Ditto search and conditional requests.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;WoT to OpenAPI Generator&lt;/strong&gt;: run with model base URL, model name, and version (and optionally Ditto base URL); integrate into CI to keep API docs aligned with your Thing Models.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more on WoT in Ditto (definitions, skeleton generation, Thing Descriptions), see the &lt;a href=&quot;basic-wot-integration.html&quot;&gt;WoT integration documentation&lt;/a&gt; and the &lt;a href=&quot;2022-03-03-wot-integration.html&quot;&gt;WoT integration blog post&lt;/a&gt;. For the tools themselves, go to &lt;a href=&quot;https://github.com/eclipse-ditto/ditto-wot-tooling&quot;&gt;eclipse-ditto/ditto-wot-tooling&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;feedback&quot;&gt;Feedback?&lt;/h2&gt;

&lt;p&gt;Please &lt;a href=&quot;feedback.html&quot;&gt;get in touch&lt;/a&gt; if you have feedback or questions about the WoT tooling.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;figure&gt;&lt;img class=&quot;docimage&quot; src=&quot;images/ditto.svg&quot; alt=&quot;Ditto&quot; style=&quot;max-width: 500px&quot; /&gt;&lt;/figure&gt;

&lt;p&gt;–&lt;br /&gt;
The Eclipse Ditto team&lt;/p&gt;
</description>
            <pubDate>Mon, 02 Feb 2026 00:00:00 +0000</pubDate>
            <link>https://www.eclipse.dev/ditto/2026-02-02-wot-tooling-blog.html</link>
            <guid isPermaLink="true">https://www.eclipse.dev/ditto/2026-02-02-wot-tooling-blog.html</guid>
            
            <category>blog</category>
            
            <category>wot</category>
            
            <category>http</category>
            
            
        </item>
        
        <item>
            <title>Announcing Eclipse Ditto Release 3.8.0</title>
            <description>&lt;p&gt;Eclipse Ditto team is excited to announce the availability of a new minor release, including new features: 
Ditto &lt;a href=&quot;https://projects.eclipse.org/projects/iot.ditto/releases/3.8.0&quot;&gt;3.8.0&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;adoption&quot;&gt;Adoption&lt;/h2&gt;

&lt;p&gt;Companies are willing to show their adoption of Eclipse Ditto publicly: 
&lt;a href=&quot;https://iot.eclipse.org/adopters/?#iot.ditto&quot;&gt;https://iot.eclipse.org/adopters/?#iot.ditto&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you use Eclipse Ditto it would be great to support the project by putting your logo there.&lt;/p&gt;

&lt;h2 id=&quot;changelog&quot;&gt;Changelog&lt;/h2&gt;

&lt;p&gt;The main improvements and additions of Ditto 3.8.0 are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Diverting&lt;/strong&gt; Ditto &lt;strong&gt;connection responses&lt;/strong&gt; to other connections (e.g. to allow multi-protocol workflows)&lt;/li&gt;
  &lt;li&gt;Dynamically &lt;strong&gt;re-configuring WoT validation settings&lt;/strong&gt; without restarting Ditto&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Enforcing&lt;/strong&gt; that WoT model based &lt;strong&gt;thing definitions are used&lt;/strong&gt; and match a certain pattern when &lt;strong&gt;creating new things&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Support for &lt;strong&gt;OAuth2 “password” grant&lt;/strong&gt; type for &lt;strong&gt;authenticating outbound HTTP connections&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Configure JWT claims&lt;/strong&gt; to be &lt;strong&gt;added&lt;/strong&gt; as information to command &lt;strong&gt;headers&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Added support for &lt;strong&gt;client certificate based authentication&lt;/strong&gt; for &lt;strong&gt;Kafka and AMQP 1.0&lt;/strong&gt; connections&lt;/li&gt;
  &lt;li&gt;Extend &lt;strong&gt;“Normalized”&lt;/strong&gt; connection &lt;strong&gt;payload mapper&lt;/strong&gt; to include &lt;strong&gt;deletion events&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Support &lt;strong&gt;silent token refresh&lt;/strong&gt; in the &lt;strong&gt;Ditto UI&lt;/strong&gt; when using &lt;strong&gt;SSO via OAuth2/OIDC&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Enhance &lt;strong&gt;conditional updates&lt;/strong&gt; for &lt;strong&gt;merge thing commands&lt;/strong&gt; to contain &lt;strong&gt;several conditions&lt;/strong&gt; to dynamically decide which parts of a thing to update and which not&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following non-functional work is also included:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Improving&lt;/strong&gt; WoT based &lt;strong&gt;validation performance&lt;/strong&gt; for &lt;strong&gt;merge&lt;/strong&gt; commands&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Enhancing distributed tracing&lt;/strong&gt;, e.g. with a span for the authentication step and by adding the error response for failed API requests&lt;/li&gt;
  &lt;li&gt;Updating dependencies to their latest versions&lt;/li&gt;
  &lt;li&gt;Providing &lt;strong&gt;additional configuration options&lt;/strong&gt; to &lt;strong&gt;Helm values&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following notable fixes are included:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Fixing &lt;strong&gt;nginx CORS configuration&lt;/strong&gt; which caused &lt;strong&gt;Safari / iOS&lt;/strong&gt; browsers to fail with &lt;strong&gt;CORS errors&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Fixing &lt;strong&gt;transitive resolving of Thing Models&lt;/strong&gt; referenced with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tm:ref&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Fixing &lt;strong&gt;sorting on array fields&lt;/strong&gt; in Ditto search&lt;/li&gt;
  &lt;li&gt;Fixing issues around &lt;strong&gt;“put-metadata”&lt;/strong&gt; in combination &lt;strong&gt;with merge commands&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Fixing that &lt;strong&gt;certificate chains&lt;/strong&gt; for &lt;strong&gt;client certificate based authentication&lt;/strong&gt; in Ditto connection was not fully parsed&lt;/li&gt;
  &lt;li&gt;Fixing &lt;strong&gt;deployment of Ditto on OpenShift&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please have a look at the &lt;a href=&quot;release_notes_380.html&quot;&gt;3.8.0 release notes&lt;/a&gt; for a more detailed information on the release.&lt;/p&gt;

&lt;h2 id=&quot;artifacts&quot;&gt;Artifacts&lt;/h2&gt;

&lt;p&gt;The new Java artifacts have been published at the &lt;a href=&quot;https://repo.eclipse.org/content/repositories/ditto/&quot;&gt;Eclipse Maven repository&lt;/a&gt;
as well as &lt;a href=&quot;https://repo1.maven.org/maven2/org/eclipse/ditto/&quot;&gt;Maven central&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The Ditto JavaScript client release was published on &lt;a href=&quot;https://www.npmjs.com/~eclipse_ditto&quot;&gt;npmjs.com&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/@eclipse-ditto/ditto-javascript-client-dom&quot;&gt;@eclipse-ditto/ditto-javascript-client-dom&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/@eclipse-ditto/ditto-javascript-client-node&quot;&gt;@eclipse-ditto/ditto-javascript-client-node&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Docker images have been pushed to Docker Hub:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-policies/&quot;&gt;eclipse/ditto-policies&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-things/&quot;&gt;eclipse/ditto-things&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-things-search/&quot;&gt;eclipse/ditto-things-search&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-gateway/&quot;&gt;eclipse/ditto-gateway&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-connectivity/&quot;&gt;eclipse/ditto-connectivity&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Ditto Helm chart has been published to Docker Hub:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto/&quot;&gt;eclipse/ditto&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;figure&gt;&lt;img class=&quot;docimage&quot; src=&quot;images/ditto.svg&quot; alt=&quot;Ditto&quot; style=&quot;max-width: 500px&quot; /&gt;&lt;/figure&gt;

&lt;p&gt;–&lt;br /&gt;
The Eclipse Ditto team&lt;/p&gt;
</description>
            <pubDate>Fri, 10 Oct 2025 00:00:00 +0000</pubDate>
            <link>https://www.eclipse.dev/ditto/2025-10-10-release-announcement-380.html</link>
            <guid isPermaLink="true">https://www.eclipse.dev/ditto/2025-10-10-release-announcement-380.html</guid>
            
            <category>blog</category>
            
            
        </item>
        
        <item>
            <title>Response diversion - Multi-protocol workflows made easy</title>
            <description>&lt;p&gt;Today we’re excited to announce a powerful new connectivity feature in Eclipse Ditto: &lt;strong&gt;Response Diversion&lt;/strong&gt;. 
This feature enables sophisticated multiprotocol workflows by allowing responses from one connection to be redirected to another connection instead of being sent to the originally configured reply target.&lt;/p&gt;

&lt;p&gt;With response diversion, Eclipse Ditto becomes even more versatile in bridging different IoT protocols and systems, 
enabling complex routing scenarios that were previously challenging or impossible to achieve.&lt;/p&gt;

&lt;h2 id=&quot;the-challenge-multi-protocol-iot-landscapes&quot;&gt;The challenge: Multi-protocol IoT landscapes&lt;/h2&gt;

&lt;p&gt;Modern IoT deployments often involve multiple protocols and systems working together. Consider these common scenarios:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Cloud integration&lt;/strong&gt;: Your devices use MQTT to communicate with AWS IoT Core, but your analytics pipeline consumes data via Kafka&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Protocol translation&lt;/strong&gt;: Legacy systems expect HTTP webhooks, but your devices communicate via AMQP&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Response aggregation&lt;/strong&gt;: You want to collect all device responses in a central monitoring system regardless of the original protocol&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Until now, implementing such multiprotocol workflows required complex external routing logic or multiple intermediate systems. 
Response diversion brings this capability directly into Ditto’s connectivity layer.&lt;/p&gt;

&lt;h2 id=&quot;how-response-diversion-works&quot;&gt;How response diversion works&lt;/h2&gt;

&lt;p&gt;Response diversion is configured at the connection source level using a key in the specific config and special header mapping keys:&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;headerMapping&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;divert-response-to-connection&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;target-connection-id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; 
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;divert-expected-response-types&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;response,error,nack&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
   &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; 
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;specificConfig&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;is-diversion-source&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And in the target connection, by defining a target.
In the case of multiple sources one or exactly the same number of sources targets are required.
If multiple targets are configured they are mapped to the sources by order.
Only diverted responses will be accepted by source connections which ids are defined in the specific config under the key
‘authorized-connections-as-sources’ in a comma separate format.&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;target-connection-id-1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;targets&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;address&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;command/redirected/response&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;topics&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;qos&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;authorizationContext&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;pre:ditto&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;headerMapping&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;specificConfig&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;is-diversion-target&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;targets&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;address&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;command/redirected/response&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;topics&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;qos&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;authorizationContext&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;pre:ditto&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;headerMapping&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;specificConfig&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;is-diversion-target&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;authorized-connections-as-sources&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;target-connection-id-1,...&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;


&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When a command is received through a source with response diversion configured, Ditto intercepts the response and routes it through the specified target connection instead of the original reply target.&lt;/p&gt;

&lt;h2 id=&quot;real-world-use-case-aws-iot-core-with-kafka&quot;&gt;Real-world use case: AWS IoT Core with Kafka&lt;/h2&gt;

&lt;p&gt;Let’s explore a practical scenario that demonstrates the power of response diversion. In this setup:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Devices communicate with &lt;strong&gt;AWS IoT Core&lt;/strong&gt; via MQTT (bidirectional)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Apache Kafka&lt;/strong&gt; IoT Core pushes device commands to a Kafka topic&lt;/li&gt;
  &lt;li&gt;Device commands are consumed from Kafka topics&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Responses must go back to AWS IoT Core via MQTT&lt;/strong&gt; (since IoT Core doesn’t support Kafka consumers)&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│  AWS IoT Core   │    │   Kafka Bridge  │    │  Apache Kafka   │    │  Eclipse Ditto  │
│    (MQTT)       │    │   /Analytics    │    │                 │    │                 │
│                 │    │                 │    │                 │    │                 │
│ ┌─────────────┐ │    │ ┌─────────────┐ │    │ ┌─────────────┐ │    │ ┌─────────────┐ │
│ │Device       │ │───▶│ │MQTT→Kafka   │ │───▶│ │device-      │ │───▶│ │Kafka Source │ │
│ │Commands     │ │    │ │Bridge       │ │    │ │commands     │ │    │ │Connection   │ │
│ │(MQTT topics)│ │    │ │             │ │    │ │topic        │ │    │ │             │ │
│ └─────────────┘ │    │ └─────────────┘ │    │ └─────────────┘ │    │ └─────────────┘ │
│        ▲        │    │                 │    │                 │    │        │        │
│        │        │    │                 │    │                 │    │        ▼        │
│        │        │    │                 │    │                 │    │ ┌─────────────┐ │
│        │        │    │                 │    │                 │    │ │Command      │ │
│        │        │    │                 │    │                 │    │ │Processing   │ │
│        │        │    │                 │    │                 │    │ │             │ │
│        │        │    │                 │    │                 │    │ └─────────────┘ │
│        │        │    │                 │    │                 │    │        │        │
│        │        │    │                 │    │                 │    │        ▼        │
│        │        │    │                 │    │                 │    │ ┌─────────────┐ │
│        │        │    │                 │    │                 │    │ │Response     │ │
│        │        │    │                 │    │                 │    │ │Diversion    │ │
│        │        │    │                 │    │                 │    │ │Interceptor  │ │
│        │        │    │                 │    │                 │    │ └─────────────┘ │
│        │        │    │                 │    │                 │    │        │        │
│        │        │    │                 │    │                 │    │        ▼        │
│ ┌─────────────┐ │    │                 │    │                 │    │ ┌─────────────┐ │
│ │Device       │ │◀───┼─────────────────┼────┼─────────────────┼────│ │MQTT Target  │ │
│ │Responses    │ │    │                 │    │                 │    │ │Connection   │ │
│ │(MQTT topics)│ │    │                 │    │                 │    │ │(AWS IoT)    │ │
│ └─────────────┘ │    │                 │    │                 │    │ └─────────────┘ │
└─────────────────┘    └─────────────────┘    └─────────────────┘    └─────────────────┘

Legend:
───▶ Command Flow (MQTT → Kafka → Ditto)
◀─── Response Flow (Ditto → MQTT, bypassing Kafka)

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;example-configuration&quot;&gt;Example Configuration&lt;/h3&gt;

&lt;p&gt;First, create the Kafka connection that consumes device commands:&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;kafka-commands-connection&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;connectionType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;kafka&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;connectionStatus&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;open&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;uri&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tcp://kafka-broker:9092&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;specificConfig&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;bootstrapServers&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;kafka-broker:9092&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;saslMechanism&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;plain&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;sources&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;addresses&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;device-commands&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;authorizationContext&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;ditto:kafka-consumer&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;headerMapping&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;device-id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;{{ header:device-id }}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;divert-response-to-connection&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;aws-iot-mqtt-connection&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;divert-expected-response-types&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;response,error&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Next, create the MQTT connection that will handle diverted responses:&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;aws-iot-mqtt-connection&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; 
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;connectionType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;mqtt&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;connectionStatus&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;open&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;uri&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;ssl://your-iot-endpoint.amazonaws.com:8883&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;sources&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;targets&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;address&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;device/{{ header:device-id }}/response&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;topics&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;headerMapping&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;device-id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;{{ header:device-id }}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;correlation-id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;{{ header:correlation-id }}&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;specificConfig&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;is-diversion-target&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;flow-explanation&quot;&gt;Flow explanation&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Command ingestion&lt;/strong&gt;: Kafka connection consumes device commands from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;device-commands&lt;/code&gt; topic&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Response diversion&lt;/strong&gt;: Commands are configured to divert responses to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aws-iot-mqtt-connection&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Response routing&lt;/strong&gt;: Responses are automatically published to AWS IoT Core via MQTT on the device-specific response topic&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Device notification&lt;/strong&gt;: Devices receive responses via their subscribed MQTT topics in AWS IoT Core&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This setup enables a seamless flow from Kafka-based systems back to MQTT-based device communication without requiring external routing logic.&lt;/p&gt;

&lt;h2 id=&quot;try-it-out&quot;&gt;Try it out&lt;/h2&gt;

&lt;p&gt;Response diversion is available starting with Eclipse Ditto version 3.8.0. Update your deployment and start experimenting with multi-protocol workflows!&lt;/p&gt;

&lt;p&gt;The feature documentation provides comprehensive configuration examples and troubleshooting guidance. We’d love to hear about your use cases and feedback.&lt;/p&gt;

&lt;p&gt;Get started with response diversion today and unlock new possibilities for your IoT connectivity architecture.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;figure&gt;&lt;img class=&quot;docimage&quot; src=&quot;images/ditto.svg&quot; alt=&quot;Ditto&quot; style=&quot;max-width: 500px&quot; /&gt;&lt;/figure&gt;

&lt;p&gt;–&lt;br /&gt;
The Eclipse Ditto team&lt;/p&gt;
</description>
            <pubDate>Thu, 09 Oct 2025 00:00:00 +0000</pubDate>
            <link>https://www.eclipse.dev/ditto/2025-10-09-response-diversion.html</link>
            <guid isPermaLink="true">https://www.eclipse.dev/ditto/2025-10-09-response-diversion.html</guid>
            
            <category>blog</category>
            
            <category>connectivity</category>
            
            
        </item>
        
        <item>
            <title>Announcing Eclipse Ditto Release 3.7.0</title>
            <description>&lt;p&gt;Eclipse Ditto team is excited to announce the availability of a new minor release, including new features: 
Ditto &lt;a href=&quot;https://projects.eclipse.org/projects/iot.ditto/releases/3.7.0&quot;&gt;3.7.0&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The focus of this release was to ease the migration of Things “definitions” (following WoT Things Models) and to provide 
a new Policy decision API to check permissions for a logged-in user.&lt;br /&gt;
On the operating side, it is now possible to configure extra fields to be proactively added to Things in order to optimize
cluster roundtrips and to throttle the amount of updates to the search index after a re-used policy was updated.&lt;/p&gt;

&lt;h2 id=&quot;adoption&quot;&gt;Adoption&lt;/h2&gt;

&lt;p&gt;Companies are willing to show their adoption of Eclipse Ditto publicly: 
&lt;a href=&quot;https://iot.eclipse.org/adopters/?#iot.ditto&quot;&gt;https://iot.eclipse.org/adopters/?#iot.ditto&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you use Eclipse Ditto it would be great to support the project by putting your logo there.&lt;/p&gt;

&lt;h2 id=&quot;changelog&quot;&gt;Changelog&lt;/h2&gt;

&lt;p&gt;The main improvements and additions of Ditto 3.7.0 are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Introduce new &lt;strong&gt;Policy decision API&lt;/strong&gt; to check with a single request what a logged-in user is allowed to do with a specific resource&lt;/li&gt;
  &lt;li&gt;Include current &lt;strong&gt;entity revision&lt;/strong&gt; of a resource (thing and policy) in the response of requests (commands) and in all emitted events&lt;/li&gt;
  &lt;li&gt;Support updating referenced WoT ThingModel based &lt;strong&gt;thing definition&lt;/strong&gt; for a Thing by defining a migration payload and when to apply it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following non-functional work is also included:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Add option to &lt;strong&gt;configure pre-defined extra fields&lt;/strong&gt; (enrichments) to be proactively added internally in Ditto in order to save cluster roundtrips&lt;/li&gt;
  &lt;li&gt;Include &lt;strong&gt;throttling configuration option&lt;/strong&gt; for updating the search index as a result of a policy update targeting many things&lt;/li&gt;
  &lt;li&gt;Add namespace to Ditto Helm chart managed Kubernetes resources&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following notable fixes are included:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Fix flattening of JSON objects in arrays when an exists() RQL condition was used e.g. as a Ditto evaluated condition&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please have a look at the &lt;a href=&quot;release_notes_370.html&quot;&gt;3.7.0 release notes&lt;/a&gt; for a more detailed information on the release.&lt;/p&gt;

&lt;h2 id=&quot;artifacts&quot;&gt;Artifacts&lt;/h2&gt;

&lt;p&gt;The new Java artifacts have been published at the &lt;a href=&quot;https://repo.eclipse.org/content/repositories/ditto/&quot;&gt;Eclipse Maven repository&lt;/a&gt;
as well as &lt;a href=&quot;https://repo1.maven.org/maven2/org/eclipse/ditto/&quot;&gt;Maven central&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The Ditto JavaScript client release was published on &lt;a href=&quot;https://www.npmjs.com/~eclipse_ditto&quot;&gt;npmjs.com&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/@eclipse-ditto/ditto-javascript-client-dom&quot;&gt;@eclipse-ditto/ditto-javascript-client-dom&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/@eclipse-ditto/ditto-javascript-client-node&quot;&gt;@eclipse-ditto/ditto-javascript-client-node&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Docker images have been pushed to Docker Hub:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-policies/&quot;&gt;eclipse/ditto-policies&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-things/&quot;&gt;eclipse/ditto-things&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-things-search/&quot;&gt;eclipse/ditto-things-search&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-gateway/&quot;&gt;eclipse/ditto-gateway&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-connectivity/&quot;&gt;eclipse/ditto-connectivity&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Ditto Helm chart has been published to Docker Hub:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto/&quot;&gt;eclipse/ditto&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;figure&gt;&lt;img class=&quot;docimage&quot; src=&quot;images/ditto.svg&quot; alt=&quot;Ditto&quot; style=&quot;max-width: 500px&quot; /&gt;&lt;/figure&gt;

&lt;p&gt;–&lt;br /&gt;
The Eclipse Ditto team&lt;/p&gt;
</description>
            <pubDate>Wed, 26 Feb 2025 00:00:00 +0000</pubDate>
            <link>https://www.eclipse.dev/ditto/2025-02-26-release-announcement-370.html</link>
            <guid isPermaLink="true">https://www.eclipse.dev/ditto/2025-02-26-release-announcement-370.html</guid>
            
            <category>blog</category>
            
            
        </item>
        
        <item>
            <title>Announcing Eclipse Ditto Release 3.6.0</title>
            <description>&lt;p&gt;After a longer time of “bugfix releases” only, the Eclipse Ditto team is once again happy to announce the availability
of a new minor release, including new features: Ditto &lt;a href=&quot;https://projects.eclipse.org/projects/iot.ditto/releases/3.6.0&quot;&gt;3.6.0&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The most work in this release went into the enforcement/validation of a linked WoT (Web of Thing) “Thing Model” to make
sure that a Ditto managed digital twin can only be modified in ways which are valid based on the defined WoT model.&lt;/p&gt;

&lt;p&gt;But also other features like SSO in the Ditto-UI were added, so inform yourself in this blogpost about the changes in 
the new release.&lt;/p&gt;

&lt;h2 id=&quot;adoption&quot;&gt;Adoption&lt;/h2&gt;

&lt;p&gt;Companies are willing to show their adoption of Eclipse Ditto publicly: 
&lt;a href=&quot;https://iot.eclipse.org/adopters/?#iot.ditto&quot;&gt;https://iot.eclipse.org/adopters/?#iot.ditto&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you use Eclipse Ditto it would be great to support the project by putting your logo there.&lt;/p&gt;

&lt;h2 id=&quot;changelog&quot;&gt;Changelog&lt;/h2&gt;

&lt;p&gt;The main improvements and additions of Ditto 3.6.0 are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;WoT (Web of Things)&lt;/strong&gt; Thing Model based validation of modifications to things and action/event payloads&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;AWS IAM based authentication&lt;/strong&gt; against &lt;strong&gt;MongoDB&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Configure &lt;strong&gt;defined aggregation queries&lt;/strong&gt; to be &lt;strong&gt;exposed as Prometheus metrics&lt;/strong&gt; by Ditto periodically&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;SSO (Single-Sign-On)&lt;/strong&gt; support in the Ditto UI via OpenID connect provider configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following non-functional work is also included:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Update Java runtime to &lt;strong&gt;run Eclipse Ditto with&lt;/strong&gt; to &lt;strong&gt;Java 21&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Run &lt;strong&gt;Ditto system tests&lt;/strong&gt; in &lt;strong&gt;GitHub actions&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following notable fixes are included:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Fix &lt;strong&gt;JWT placeholder&lt;/strong&gt; not resolving correctly in &lt;strong&gt;JSON arrays nested&lt;/strong&gt; in JSON objects&lt;/li&gt;
  &lt;li&gt;Fix &lt;strong&gt;retrieving a Thing&lt;/strong&gt; at a &lt;strong&gt;given historical timestamp&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Generating UNIX “Epoch” as neutral element when creating new things based on WoT TM models for types declared as “date-time” format&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please have a look at the &lt;a href=&quot;release_notes_360.html&quot;&gt;3.6.0 release notes&lt;/a&gt; for a more detailed information on the release.&lt;/p&gt;

&lt;h2 id=&quot;artifacts&quot;&gt;Artifacts&lt;/h2&gt;

&lt;p&gt;The new Java artifacts have been published at the &lt;a href=&quot;https://repo.eclipse.org/content/repositories/ditto/&quot;&gt;Eclipse Maven repository&lt;/a&gt;
as well as &lt;a href=&quot;https://repo1.maven.org/maven2/org/eclipse/ditto/&quot;&gt;Maven central&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The Ditto JavaScript client release was published on &lt;a href=&quot;https://www.npmjs.com/~eclipse_ditto&quot;&gt;npmjs.com&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/@eclipse-ditto/ditto-javascript-client-dom&quot;&gt;@eclipse-ditto/ditto-javascript-client-dom&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/@eclipse-ditto/ditto-javascript-client-node&quot;&gt;@eclipse-ditto/ditto-javascript-client-node&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Docker images have been pushed to Docker Hub:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-policies/&quot;&gt;eclipse/ditto-policies&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-things/&quot;&gt;eclipse/ditto-things&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-things-search/&quot;&gt;eclipse/ditto-things-search&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-gateway/&quot;&gt;eclipse/ditto-gateway&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-connectivity/&quot;&gt;eclipse/ditto-connectivity&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Ditto Helm chart has been published to Docker Hub:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto/&quot;&gt;eclipse/ditto&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;figure&gt;&lt;img class=&quot;docimage&quot; src=&quot;images/ditto.svg&quot; alt=&quot;Ditto&quot; style=&quot;max-width: 500px&quot; /&gt;&lt;/figure&gt;

&lt;p&gt;–&lt;br /&gt;
The Eclipse Ditto team&lt;/p&gt;
</description>
            <pubDate>Mon, 07 Oct 2024 00:00:00 +0000</pubDate>
            <link>https://www.eclipse.dev/ditto/2024-10-07-release-announcement-360.html</link>
            <guid isPermaLink="true">https://www.eclipse.dev/ditto/2024-10-07-release-announcement-360.html</guid>
            
            <category>blog</category>
            
            
        </item>
        
        <item>
            <title>Access Ditto Things from an Asset Administration Shell</title>
            <description>&lt;p&gt;Integrating digital representations of devices into an IT infrastructure is a recurring task in different domains and application areas.
To address this challenge in Industry 4.0 scenarios along the supply chain, the community specified the &lt;a href=&quot;https://industrialdigitaltwin.org/&quot;&gt;Asset Administration Shell&lt;/a&gt; within the Industrial Digital Twin Association (IDTA) to handle all kinds of information of a physical asset over its lifecycle.&lt;/p&gt;

&lt;p&gt;Eclipse Ditto provides a backend for handling such device data as Things and takes care of a number of general tasks that are otherwise easy to be done wrong,
such as handling device connectivity over different protocols or state management. Therefore, it is promising to use the benefits of Eclipse Ditto for populating an AAS infrastructure when the devices already communicate with an existing instance of Eclipse Ditto.&lt;/p&gt;

&lt;p&gt;In this post we want to share our solution and learnings from setting up an AAS infrastructure based on &lt;a href=&quot;https://eclipse.dev/basyx/&quot;&gt;Eclipse Basyx&lt;/a&gt; and Eclipse Ditto as a source for device state.&lt;/p&gt;

&lt;figure&gt;&lt;img class=&quot;docimage&quot; src=&quot;images/blog/2024-02-15-integrating-ditto-ass-basyx/basic-interaction.svg&quot; alt=&quot;User-device interaction via AAS and IoT backend&quot; style=&quot;max-width: 1000px&quot; /&gt;&lt;/figure&gt;

&lt;p&gt;&lt;em&gt;Figure 1:  User-device interaction via BaSyx and Ditto&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;background&quot;&gt;Background&lt;/h2&gt;

&lt;p&gt;We start with some background on the AAS and Eclipse Basyx. If you are allready familiar with both, it is safe to skip this section.&lt;/p&gt;

&lt;h3 id=&quot;asset-administration-shell&quot;&gt;Asset Administration Shell&lt;/h3&gt;

&lt;p&gt;The Asset Administration Shell (AAS) is a standardization effort of
the Industrial Digital Twin Association (IDTA) that originated from the
Platform Industry 4.0 (I4.0) (&lt;a href=&quot;https://industrialdigitaltwin.org/en/wp-content/uploads/sites/2/2023/04/IDTA-01001-3-0_SpecificationAssetAdministrationShell_Part1_Metamodel.pdf&quot;&gt;AAS Spec Part I&lt;/a&gt;; &lt;a href=&quot;https://industrialdigitaltwin.org/en/wp-content/uploads/sites/2/2023/04/IDTA-01002-3-0_SpecificationAssetAdministrationShell_Part2_API.pdf&quot;&gt;AAS Spec Part II&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;An AAS is a digital representation of a physical asset and consists of one or more submodels. Each submodel contains a structured set of submodel elements.
Submodels, as well as their submodel elements, can either be a type or an instance.
The AAS metamodel defines the possible elements for modeling an AAS like Asset, AssetAdminstrationShell (AAS), Submodel (SM), SubmodelElementCollection (SMEC),
Property, and SubmodelElement (SME). You can find further details &lt;a href=&quot;https://www.plattform-i40.de/IP/Redaktion/EN/Downloads/Publikation/2021_What-is-the-AAS.html&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;https://industrialdigitaltwin.org/en/wp-content/uploads/sites/2/2023/04/IDTA-01001-3-0_SpecificationAssetAdministrationShell_Part1_Metamodel.pdf&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A user who wants to interact with an AAS over HTTP follows the sequence of service calls depicted in Figure 2.
The flow starts by requesting an AAS ID from the AAS discovery interface based on a (local) specific asset ID or a global asset ID. An example of such an asset ID is a serial number written on the device. With the AAS ID, the user retrieves the endpoint for the AAS through the AAS registry interface.
The user then requests the SM ID from that AAS endpoint and uses this SM ID to get the SM endpoint from the SM Registry.
From that SM endpoint, the user can request the SME, which contains the required value.&lt;/p&gt;

&lt;figure&gt;&lt;img class=&quot;docimage&quot; src=&quot;images/blog/2024-02-15-integrating-ditto-ass-basyx/aas-sequenz.svg&quot; alt=&quot;Sequence of data flow through AAS infrastructure&quot; style=&quot;max-width: 1000px&quot; /&gt;&lt;/figure&gt;

&lt;p&gt;&lt;em&gt;Figure 2: Sequence of data flow through AAS infrastructure&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you want to dig deeper into the specifics of the AAS, consult the &lt;a href=&quot;https://www.plattform-i40.de/IP/Redaktion/DE/Downloads/Publikation/AAS-ReadingGuide_202201.html&quot;&gt;AAS Reading Guide&lt;/a&gt;, which helps the interested reader to navigate through the available material.&lt;/p&gt;

&lt;h3 id=&quot;eclipse-basyx&quot;&gt;Eclipse BaSyx&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://wiki.eclipse.org/BaSyx_/_Documentation_/_Components&quot;&gt;Eclipse BaSyx&lt;/a&gt; is an open-source project hosted by the Eclipse Foundation providing components to deploy an Industry 4.0 middleware.
Apart from other features, Eclipse BaSyx provides several easy-to-use off-the-shelf components to realize an AAS infrastructure:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://wiki.eclipse.org/BaSyx_/_Documentation_/_Components_/_AAS_Server&quot;&gt;AAS Server Component&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://wiki.eclipse.org/BaSyx_/_Documentation_/_Components_/_Registry&quot;&gt;Registry Component&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://wiki.eclipse.org/BaSyx_/_Documentation_/_Components_/_DataBridge&quot;&gt;DataBridge Component&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://wiki.eclipse.org/BaSyx_/_Documentation_/_Components_/_AAS_Web_UI&quot;&gt;AAS Web UI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can pull them from Docker Hub or &lt;a href=&quot;https://wiki.eclipse.org/BaSyx_/_Documentation_/_Components_/_Docker&quot;&gt;follow the instructions&lt;/a&gt; to build them yourself.&lt;/p&gt;

&lt;p&gt;In this post, we mainly work with the AAS Server Component and the Registry Component.&lt;/p&gt;

&lt;h2 id=&quot;architectural-considerations&quot;&gt;Architectural Considerations&lt;/h2&gt;

&lt;p&gt;Making Eclipse Ditto Things available in an AAS infrastructure, in our case from the Eclipse Basyx project, boils down to making Thing data available as Submodels of an AAS accessible via the AAS Interface.&lt;/p&gt;

&lt;p&gt;We see three approaches to achieve this:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;BaSyx AAS SM server &lt;em&gt;pulls&lt;/em&gt; the current state from Eclipse Ditto via a &lt;em&gt;wrapper&lt;/em&gt; around Eclipse Ditto.
This approach requires the creation of a custom AAS infrastructure around Eclipse Ditto without the chance of reusing existing components of the Eclipse Basyx project.
The Eclipse Ditto project followed a comparable approach to support &lt;a href=&quot;2022-03-03-wot-integration.html&quot;&gt;Web of Things&lt;/a&gt; (WoT) definitions, which is another specification to integrate IoT devices from different contexts and align their utilized data model.
Ditto now allows the generation of new Things based on a WoT Thing Description.&lt;/li&gt;
  &lt;li&gt;BaSyx AAS SM server &lt;em&gt;pulls&lt;/em&gt; the current state from Eclipse Ditto via a &lt;em&gt;bridge&lt;/em&gt; component, which Eclipse Basyx already provides.
To integrate the bridge, the BaSyx SM-server component has a delegation feature, where the user can configure an SME with an endpoint to which the server delegates incoming requests.
The configured endpoint can reference the bridge that then retrieves the actual data from Ditto and applies transformation logic.&lt;/li&gt;
  &lt;li&gt;Eclipse Ditto &lt;em&gt;pushes&lt;/em&gt; the latest updates to a BaSyx SM server.
For this approach, we configure Eclipse Ditto to notify the BaSyx SM server about any change to the relevant Things. During the creation of the notification message, Ditto applies a payload mapping to transform the data into the AAS format. The BaSyx SM server then stores the received submodel element and responds directly to the requests by the users.&lt;/li&gt;
&lt;/ul&gt;

&lt;figure&gt;&lt;img class=&quot;docimage&quot; src=&quot;images/blog/2024-02-15-integrating-ditto-ass-basyx/push.svg&quot; alt=&quot;Push approach sequence&quot; style=&quot;max-width: 1000px&quot; /&gt;&lt;/figure&gt;

&lt;p&gt;&lt;em&gt;Figure 3: Push approach sequence&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We follow the push approach here because it treats the AAS infrastructure as a blackbox and almost all configuration happens within Eclipse Ditto.&lt;/p&gt;

&lt;h2 id=&quot;mapping-of-data-models&quot;&gt;Mapping of Data Models&lt;/h2&gt;

&lt;p&gt;Eclipse Ditto and Eclipse Basyx work with different data structures and conceptual elements to represent device and asset data. Since we want to convert between these data models, we need to come up with a mapping between them.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Eclipse Ditto&lt;/th&gt;
      &lt;th&gt;Asset Administration Shell&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Namespace&lt;/td&gt;
      &lt;td&gt;Asset Administration Shell&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Thing&lt;/td&gt;
      &lt;td&gt;—&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Features&lt;/td&gt;
      &lt;td&gt;Submodel&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Property&lt;/td&gt;
      &lt;td&gt;Submodel Element&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Attribute&lt;/td&gt;
      &lt;td&gt;Submodel Element&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;em&gt;Table 1: Concept mapping from Eclipse Ditto to the AAS&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We map a Ditto &lt;a href=&quot;basic-namespaces-and-names.html#namespace&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Namespace&lt;/code&gt;&lt;/a&gt; to a single AAS. An AAS holds multiple SMs, and not all of these SMs necessarily have counterparts in Ditto. We thus treat a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Thing&lt;/code&gt; as an opaque concept and do not define an explicit mapping for a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Thing&lt;/code&gt; but map each &lt;a href=&quot;basic-feature.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;feature&lt;/code&gt;&lt;/a&gt; to one SM.
&lt;a href=&quot;basic-feature.html#feature-properties&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;property&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;basic-thing.html#attributes&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Attribute&lt;/code&gt;&lt;/a&gt; are mapped to SMEs.&lt;/p&gt;

&lt;p&gt;By that, it is possible to have more than one Thing organized in one AAS.
This can especially be useful if an AAS organizes complex equipment with different sensors and actuators, which belong together but are organized in multiple Things.&lt;/p&gt;

&lt;h2 id=&quot;integration-steps&quot;&gt;Integration Steps&lt;/h2&gt;

&lt;p&gt;With the more theoretical details completed, we can now turn to the actual implementation and describe what is required
to integrate Eclipse Ditto into an AAS infrastructure of Eclipse BaSyx.&lt;/p&gt;

&lt;h3 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;Running instance of &lt;a href=&quot;https://eclipse.dev/ditto/&quot;&gt;Eclipse Ditto&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Running instance of &lt;a href=&quot;https://wiki.eclipse.org/BaSyx_/_Documentation_/_Components_/_AAS_Server&quot;&gt;Eclipse BaSyx AAS Server&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Running instance of &lt;a href=&quot;https://wiki.eclipse.org/BaSyx_/_Documentation_/_Components_/_Registry&quot;&gt;Eclipse BaSyx AAS Registry&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Those three instances must be available and a network connection must exist between them.
In the code snippets below, we use placeholders for the URLs of Ditto as well as BaSyx.
So, you need to replace &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;ditto-instance-url&amp;gt;&lt;/code&gt;,  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;basyx-server-instance-url&amp;gt;&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;basyx-registry-instance-url&amp;gt;&lt;/code&gt;
with the proper URLs in your environment.&lt;/p&gt;

&lt;p&gt;For our setup, we used version 3.0.1 for Eclipse Ditto and version 1.4.0 for Eclipse BaSyx.
Please note that the Ditto demo instance, does not work for the described setup and requests because it does not allow to directly invoke the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/devops&lt;/code&gt; endpoints through which we later configure connections.&lt;/p&gt;

&lt;h3 id=&quot;payload-mappers-from-ditto-to-basyx&quot;&gt;Payload Mappers from Ditto to BaSyx&lt;/h3&gt;

&lt;p&gt;Let us assume a device with a sensor named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;machine:sensor&lt;/code&gt; that is capable of measuring temperature values.
This device may send sensor data to an Eclipse Ditto instance as a Ditto Protocol message &lt;a href=&quot;protocol-overview.html&quot;&gt;Ditto Protocol message&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;topic&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;machine/sensor/things/twin/commands/modify&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;headers&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;path&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/features/temperature/properties/value&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;46&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Listing 1: Ditto Protocol message for the Thing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;machine:senor&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If the device uses another message format, you can find more details on &lt;a href=&quot;connectivity-mapping.html&quot;&gt;how to map it&lt;/a&gt; to a Ditto Protocol message.&lt;/p&gt;

&lt;p&gt;After an update to a Thing, we want Ditto to map the information to an AAS-conforming representation and forward this via an outbound connection to an AAS server.
The task in Eclipse Ditto is to define &lt;a href=&quot;connectivity-mapping.html&quot;&gt;payload mappers&lt;/a&gt; for these transformations in accordance with the mapping from &lt;a href=&quot;#mapping-of-data-models&quot;&gt;Mapping of Data Models&lt;/a&gt;. Ditto allows the usage of JavaScript to create the mappers. We thus configure connections in Ditto to the BaSyx components, where we filter for the relevant changes to a Thing and then trigger the respective mapper.&lt;/p&gt;

&lt;p&gt;We need to implement the following mappers:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Creation of an AAS triggered by creation of new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;namespaces&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Creation of a SM triggered by creation of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;feature&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Creation and update of an SME triggered by creation and modification of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;property&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;map-from-thing-creation-to-aas-creation&quot;&gt;Map from Thing Creation to AAS Creation&lt;/h4&gt;

&lt;p&gt;The next snippet performs a mapping from a Thing to an AAS.
It gets executed every time a Thing is created.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mapFromDittoProtocolMsg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;channel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;criterion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;dittoHeaders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;extra&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;headers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;dittoHeaders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;textPayload&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;conceptDictionary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;identification&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;idType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Custom&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;namespace&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;idShort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;dataSpecification&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;modelType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;AssetAdministrationShell&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;asset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;identification&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;idType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Custom&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;-asset&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;idShort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;-asset&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Instance&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;dataSpecification&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;modelType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Asset&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;embeddedDataSpecifications&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;embeddedDataSpecifications&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;views&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;submodels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;bytePayload&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;contentType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;application/json&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Ditto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;buildExternalMsg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// The external headers Object containing header values&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;textPayload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// The external mapped String&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;bytePayload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// The external mapped byte[]&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;contentType&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// The returned Content-Type&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Listing 2: Payload mapping that creates a new AAS if a new Thing appears&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As we map the Thing namespace to an AAS we only use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;namespace&lt;/code&gt;, which is the first part of the ID of a Thing.
For example &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;machine&lt;/code&gt; in our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;machine:sensor&lt;/code&gt; example Thing (Listing 1).
More precisely, the mapping creates a representation of an AAS with the ID &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;namespace&lt;/code&gt; and returns a new message with this text as payload. The Ditto connectivity service then runs the mapping and pushes the new message to the BaSyx AAS server to create the described AAS.
For example, whenever a Thing with the ID &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;machine:sensor&lt;/code&gt; is created, an AAS with the ID &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;machine&lt;/code&gt; will be created.&lt;/p&gt;

&lt;h3 id=&quot;map-from-feature-creation-to-submodel-creation&quot;&gt;Map from Feature creation to Submodel creation&lt;/h3&gt;

&lt;p&gt;The next mapper creates an AAS submodel and will be executed every time a new feature is created for a Thing.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mapFromDittoProtocolMsg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;channel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;criterion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;dittoHeaders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;extra&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  
  &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;feature_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;slice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;headers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;dittoHeaders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;textPayload&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;idType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Custom&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;AssetAdministrationShell&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;identification&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;idType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Custom&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;feature_id&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;idShort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;feature_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Instance&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;dataSpecification&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;modelType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Submodel&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;embeddedDataSpecifications&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;submodelElements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;bytePayload&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;contentType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;application/json&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Ditto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;buildExternalMsg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// The external headers Object containing header values&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;textPayload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// The external mapped String&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;bytePayload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// The external mapped byte[]&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;contentType&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// The returned Content-Type&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Listing 3: Payload mapping that creates a new AAS submodel if a new Feature appears&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Besides &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;namespace&lt;/code&gt;, this mapper uses the parameters &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;path&lt;/code&gt; from the Ditto Protocol message.
The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name&lt;/code&gt; represents the second part of the Thing-ID, e.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sensor&lt;/code&gt; from our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;machine:sensor&lt;/code&gt; example Thing (Listing 1).
The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;path&lt;/code&gt; describes the part of the Thing whose change triggered the processed Ditto Protocol message.
It may include the feature ID of the Thing or the whole path of the affected property of the Thing,
but it could be only &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/&lt;/code&gt; after the creation of a Thing. In our &lt;a href=&quot;#payload-mappers-from-ditto-to-basyx&quot;&gt;example message&lt;/a&gt; above,
the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;path&lt;/code&gt; is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/features/temperature/properties/value&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The mapping function extracts the ID of the feature from the parameter &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;path&lt;/code&gt; and uses this together with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name&lt;/code&gt;
of the Thing to build the ID of the corresponding AAS submodel. For example, whenever the feature &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;temperature&lt;/code&gt;
of a Thing called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;machine:sensor&lt;/code&gt; is created, an AAS submodel with the ID &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sensor_temperature&lt;/code&gt; in the AAS &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;machine&lt;/code&gt; will be created.&lt;/p&gt;

&lt;p&gt;Similarly to the &lt;a href=&quot;#map-from-thing-creation-to-aas-creation&quot;&gt;AAS creation mapping&lt;/a&gt;, the listed function returns a new message with a custom text payload.
Below, we will create a connection so that this payload gets pushed to the BaSyx AAS server to trigger the creation of an AAS submodel there.&lt;/p&gt;

&lt;h4 id=&quot;map-from-property-update-to-submodel-update&quot;&gt;Map from Property Update to Submodel Update&lt;/h4&gt;

&lt;p&gt;The next mapper creates an AAS submodel element.
we use it in the connection for every modification of a property in a Thing.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mapFromDittoProtocolMsg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;channel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;criterion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;dittoHeaders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;extra&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;property_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;slice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;feature_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;slice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;headers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;dittoHeaders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;dataType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;dataType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mapDataType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dataType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mapDataType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dataType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;switch &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dataType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Undefined&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;boolean&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;boolean&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;symbol&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Symbol&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bigint&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;BigInt&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Function&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nl&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Unknown&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;textPayload&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;idType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Custom&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Submodel&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;feature_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;idShort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;property_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Instance&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;valueType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;dataType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;modelType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Property&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;bytePayload&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;contentType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;application/json&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Ditto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;buildExternalMsg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// The external headers Object containing header values&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;textPayload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// The external mapped String&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;bytePayload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// The external mapped byte[]&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;contentType&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// The returned Content-Type&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Listing 4: Payload mapping that modifies an AAS submodel element if a property is changed&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The mapper extracts the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;feature_id&lt;/code&gt; and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;property_id&lt;/code&gt; from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;path&lt;/code&gt;, which is only possible if the parameter &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;path&lt;/code&gt; includes the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;property_id&lt;/code&gt;. So, in the configuration of the connection, we have to ensure that this mapper only runs for the right messages.
Moreover, we can access the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value&lt;/code&gt; of the modified &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;property&lt;/code&gt;, which will be set as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value&lt;/code&gt; in the submodel element from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;textPayload&lt;/code&gt; output.&lt;/p&gt;

&lt;p&gt;For example, if a message updates the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;path&lt;/code&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/features/temperature/properties/value&lt;/code&gt; in the Thing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;machine:sensor&lt;/code&gt;, the submodel element with the ID &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;properties_value&lt;/code&gt; in the submodel &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sensor_temperature&lt;/code&gt; will be updated with the new temperature as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We update a submodel element instead of the whole submodel if an existing Thing changes because the mapper only has access to the changed property of the Thing and no information about the other properties.
Therefore, submodel elements, which may already be part of the submodel due to previous updates, would implicitly be dropped.
With our approach, we preserve the existing properties and only modify the updated properties.&lt;/p&gt;

&lt;h4 id=&quot;create-a-connection-to-the-basyx-aas-server&quot;&gt;Create a Connection to the BaSyx AAS Server&lt;/h4&gt;

&lt;p&gt;To apply the introduced mappers, we configure a new &lt;a href=&quot;basic-connections.html&quot;&gt;Ditto connection&lt;/a&gt; to a BaSyx AAS server.
The listings below show the respective HTTP calls using curl to configure this connection.&lt;/p&gt;

&lt;p&gt;The JavaScript mappers from above are part of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;piggybackCommand.connection.mappingDefinitions&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mappingforShell&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mappingforSubmodel&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mappingforSubmodelElement&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the example, we use the placeholder &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;ditto-instance-url&amp;gt;&lt;/code&gt; for the used Ditto instance. You need to adjust to the valid URL of your environment.
We assume you have access rights to the Ditto &lt;a href=&quot;installation-operating.html#devops-commands&quot;&gt;Devops Commands&lt;/a&gt; credentials in the used instance (username: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;devops&lt;/code&gt;, password: `foobar is the default).&lt;/p&gt;

&lt;p&gt;You can change the password by setting the environment variable &lt;em&gt;DEVOPS_PASSWORD&lt;/em&gt; in the &lt;a href=&quot;architecture-services-gateway.html&quot;&gt;gateway service&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Alternatively, an already existing password can be obtained and stored as an environment variable using the following command:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DEVOPS_PWD&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;kubectl &lt;span class=&quot;nt&quot;&gt;--namespace&lt;/span&gt; ditto get secret my-ditto-gateway-secret &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;jsonpath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;{.data.devops-password}&quot;&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;base64&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--decode&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Please be aware that this command assumes Ditto has been deployed within a namespace &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ditto&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Finally, you adjust the parameter &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;piggybackCommand.connection.uri&lt;/code&gt; with the URL of the running BaSyx server to which Ditto should have network connectivity.&lt;/p&gt;

&lt;p&gt;As HTTP requires us to replace certain characters for proper processing, we encode the payload by escaping certain characters and removing the line breaks.
We replaced newlines with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\n&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&apos;&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&apos;&quot;&apos;&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl &lt;span class=&quot;nt&quot;&gt;-X&lt;/span&gt; POST &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; devops:foobar &lt;span class=&quot;nt&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Content-Type: application/json&apos;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--data-binary&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;{
    &quot;targetActorSelection&quot;: &quot;/system/sharding/connection&quot;,
    &quot;headers&quot;: {
      &quot;aggregate&quot;: false
    },
    &quot;piggybackCommand&quot;: {
      &quot;type&quot;: &quot;connectivity.commands:createConnection&quot;,
      &quot;connection&quot;: {
        &quot;id&quot;: &quot;basyxserver-http-connection&quot;,
        &quot;connectionType&quot;: &quot;http-push&quot;,
        &quot;connectionStatus&quot;: &quot;open&quot;,
        &quot;uri&quot;: &quot;&amp;lt;basyx-server-instance-url&amp;gt;:4001&quot;,
        &quot;failoverEnabled&quot;: true,
        &quot;mappingDefinitions&quot;: {
          &quot;mappingforShell&quot;: {
            &quot;mappingEngine&quot;: &quot;JavaScript&quot;,
            &quot;options&quot;: {
              &quot;outgoingScript&quot;: &quot;function mapFromDittoProtocolMsg(namespace, name, group, channel, criterion, action, path, dittoHeaders, value, status, extra) {\n  let headers = dittoHeaders;\n  let textPayload = JSON.stringify({\n    conceptDictionary: [],\n    identification: {\n      idType: &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;Custom&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;,\n      id: namespace\n    },\n    idShort: namespace,\n    dataSpecification: [],\n    modelType: {\n      name: &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;AssetAdministrationShell&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;\n    },\n    asset: {\n      identification: {\n        idType: &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;Custom&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;,\n        id: namespace + &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;-asset&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;\n      },\n      idShort: namespace + &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;-asset&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;,\n      kind: &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;Instance&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;,\n      dataSpecification: [],\n      modelType: {\n        name: &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;Asset&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;\n      },\n      embeddedDataSpecifications: []\n    },\n    embeddedDataSpecifications: [],\n    views: [],\n    submodels: []\n  });\n  let bytePayload = null;\n  let contentType = &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;application/json&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;;\n  return Ditto.buildExternalMsg(headers, textPayload, bytePayload, contentType);}&quot;            
            }
          },
          &quot;mappingforSubmodel&quot;: {
            &quot;mappingEngine&quot;: &quot;JavaScript&quot;,
            &quot;options&quot;: {
                &quot;outgoingScript&quot;: &quot;function mapFromDittoProtocolMsg(namespace, name, group, channel, criterion, action, path, dittoHeaders, value, status, extra) {\n  \n  let feature_id = path.split(&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;/&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;).slice(2);\n  let headers = dittoHeaders;\n  let textPayload = JSON.stringify(\n    {\n      parent: {\n        keys: [\n          {\n            idType: &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;Custom&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;,\n            type: &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;AssetAdministrationShell&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;,\n            value: namespace,\n            local: true\n          }\n        ]\n      },\n      identification: {\n        idType: &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;Custom&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;,\n        id: name+&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;_&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;+feature_id\n      },\n      idShort: name+&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;_&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;+feature_id,\n      kind: &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;Instance&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;,\n      dataSpecification: [],\n      modelType: {\n        name: &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;Submodel&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;\n      },\n      embeddedDataSpecifications: [],\n      submodelElements: []\n    }\n\n  );\n  let bytePayload = null;\n  let contentType = &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;application/json&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;;\n  return Ditto.buildExternalMsg(headers, textPayload, bytePayload, contentType);}&quot;
            }
          },
          &quot;mappingforSubmodelElement&quot;: {
            &quot;mappingEngine&quot;: &quot;JavaScript&quot;,
            &quot;options&quot;: {
              &quot;outgoingScript&quot;: &quot;function mapFromDittoProtocolMsg(namespace, name, group, channel, criterion, action, path, dittoHeaders, value, status, extra) {\n  let property_id = path.split(&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;/&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;).slice(3).join(&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;_&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;);\n  let feature_id = path.split(&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;/&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;).slice(2,3);\n  let headers = dittoHeaders;\n  let dataType = typeof value;\n  dataType = mapDataType(dataType)\n\n  function mapDataType(dataType) {\n    switch (dataType) {\n        case &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;undefined&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;:\n        return &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;Undefined&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;;\n        case &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;boolean&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;:\n        return &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;boolean&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;;\n        case &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;number&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;:\n        return &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;int&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;;\n        case &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;string&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;:\n        return &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;string&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;;\n        case &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;symbol&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;:\n        return &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;Symbol&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;;\n        case &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;bigint&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;:\n        return &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;BigInt&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;;\n        case &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;object&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;:\n        return &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;string&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;;\n        case &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;function&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;:\n        return &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;Function&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;;\n        default:\n        return &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;Unknown&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;;\n    }\n  }\n  let textPayload = JSON.stringify(\n  {\n    parent: {\n      keys: [\n        {\n          idType: &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;Custom&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;,\n          type: &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;Submodel&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;,\n          value: name+&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;_&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;+feature_id,\n          local: true\n        }\n      ]\n    },\n    idShort: property_id,\n    kind: &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;Instance&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;,\n    valueType: dataType,\n    modelType: {\n      name: &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;Property&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;\n    },\n    value: value\n  }\n  );\n  let bytePayload = null;\n  let contentType = &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;application/json&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;;\n  return Ditto.buildExternalMsg(headers, textPayload, bytePayload, contentType);}&quot;
            }
          }
        },
        &quot;sources&quot;: [],
        &quot;targets&quot;: [
          {
            &quot;address&quot;: &quot;PUT:/aasServer/shells/{{ thing:namespace }}&quot;,
            &quot;headerMapping&quot;: {
              &quot;content-type&quot;: &quot;{{ header:content-type }}&quot;
            },
            &quot;authorizationContext&quot;: [&quot;nginx:ditto&quot;],
            &quot;topics&quot;: [
              &quot;_/_/things/twin/events?filter=and(in(topic:action,&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;created&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;),eq(resource:path,&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;/&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;))&quot;
            ],
            &quot;payloadMapping&quot;: [
              &quot;mappingforShell&quot;
            ]
          },
          {
            &quot;address&quot;: &quot;PUT:/aasServer/shells/{{ thing:namespace }}/aas/submodels/{{ thing:name }}_{{ resource:path | fn:substring-after(&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;/features/&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;) }}&quot;,
            &quot;headerMapping&quot;: {
              &quot;content-type&quot;: &quot;{{ header:content-type }}&quot;
            },
            &quot;authorizationContext&quot;: [&quot;nginx:ditto&quot;],
            &quot;topics&quot;: [
              &quot;_/_/things/twin/events?filter=and(in(topic:action,&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;created&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;),not(eq(resource:path,&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;/features&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;)),like(resource:path,&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;/features*&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;),not(like(resource:path,&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;*properties*&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;)))&quot;
            ],
            &quot;payloadMapping&quot;: [
              &quot;mappingforSubmodel&quot;
            ]
          },
          {
            &quot;address&quot;: &quot;PUT:/aasServer/shells/{{ thing:namespace }}/aas/submodels/{{ thing:name }}_{{ resource:path | fn:substring-after(&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;/features/&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;) | fn:substring-before(&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;/properties&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;) }}/submodel/submodelElements/properties_{{ resource:path | fn:substring-after(&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;/properties/&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;) | fn:replace(&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;/&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;,&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;_&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;) }}&quot;,
            &quot;headerMapping&quot;: {
              &quot;content-type&quot;: &quot;{{ header:content-type }}&quot;
            },
            &quot;authorizationContext&quot;: [&quot;nginx:ditto&quot;],
            &quot;topics&quot;: [
              &quot;_/_/things/twin/events?filter=and(in(topic:action,&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;modified&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;),not(eq(resource:path,&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;/features&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;)),like(resource:path,&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;/features*&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;),like(resource:path,&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;*properties*&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;),not(like(resource:path,&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;*properties&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;)))&quot;
            ],
            &quot;payloadMapping&quot;: [
              &quot;mappingforSubmodelElement&quot;
            ]
          }
        ]
      }
    }
  }&apos;&lt;/span&gt; &amp;lt;ditto-instance-url&amp;gt;/devops/piggyback/connectivity
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Listing 5: Request to add a new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Connection&lt;/code&gt; to a Ditto instance&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When Ditto established the connection and our payload mappings work, it returns a successful HTTP response and otherwise an error message.&lt;/p&gt;

&lt;p&gt;Without any further means, the payload mappings defined in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;piggybackCommand.mappingDefinition&lt;/code&gt; and set in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;piggybackCommand.targets&lt;/code&gt; would get executed for all changes to a Thing.
To prevent this, we use &lt;a href=&quot;basic-changenotifications.html#filtering&quot;&gt;filtering&lt;/a&gt; with &lt;a href=&quot;basic-rql.html&quot;&gt;RQL expressions&lt;/a&gt; to make sure that our payload mappings are only executed for the correct messages.
For example, the filter:&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;_/_/things/twin/events?filter=and(in(topic:action,&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;created&apos;&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&apos;),eq(resource:path,&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;/&apos;&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&apos;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;before &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mappingforShell&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;piggybackCommands.targets[0].topics[0]&lt;/code&gt; makes sure that it only triggers for messages, which create a Thing.&lt;/p&gt;

&lt;p&gt;Another filter for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mappingForSubmodel&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pigybackCommands.targets[1].topics[0]&lt;/code&gt; makes sure, that the parameter &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;path&lt;/code&gt; contains a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;feature&lt;/code&gt; and not a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;property&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s2&quot;&gt;&quot;_/_/things/twin/events?filter=and(in(topic:action,&apos;&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&apos;created&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;),not(eq(resource:path,&apos;&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&apos;/features&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;)),like(resource:path,&apos;&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&apos;/features*&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;),not(like(resource:path,&apos;&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&apos;*properties*&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;)))&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;setup-connection-to-an-basyx-aas-registry&quot;&gt;Setup Connection to an BaSyx AAS Registry&lt;/h4&gt;

&lt;p&gt;Within an AAS environment it is required that AAS are discoverable via an AAS registry.
We make an AAS discoverable by adding an entry for that AAS into the AAS registry for a new Thing. In our setup we achieve this through the definition of a new connection between Eclipse Ditto and the BaSyx AAS Registry
with a respective payload mapping.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mapFromDittoProtocolMsg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;channel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;criterion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;dittoHeaders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;extra&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;headers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;dittoHeaders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;textPayload&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;endpoints&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;lt;basyx-server-instance-url&amp;gt;:4001/aasServer/shells/&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/aas&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;modelType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;AssetAdministrationShellDescriptor&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;identification&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;idType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Custom&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;namespace&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;idShort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;asset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;identification&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;na&quot;&gt;idType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Custom&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;-asset&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;idShort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;-asset&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Instance&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;dataSpecification&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;modelType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Asset&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;embeddedDataSpecifications&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;submodels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;bytePayload&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;contentType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;application/json&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Ditto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;buildExternalMsg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// The external headers Object containing header values&lt;/span&gt;
   &lt;span class=&quot;nx&quot;&gt;textPayload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// The external mapped String&lt;/span&gt;
   &lt;span class=&quot;nx&quot;&gt;bytePayload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// The external mapped byte[]&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;contentType&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// The returned Content-Type&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Listing 6: Snippet to add a new AAS Registry entry for an AAS&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As introduced in &lt;a href=&quot;#mapping-of-data-models&quot;&gt;Mapping of Data Models&lt;/a&gt;, we map a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;namespace&lt;/code&gt; in Ditto to an AAS.
The new entry in the BaSyx Registry has to contain the endpoint of the BaSyx AAS server, which hosts the new AAS. You find this in the script-payload in the variable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;endpoints.address&lt;/code&gt;. So you need to adapt this value in the following HTTP request to the address of the BaSyx ASS server that you are using and that was configured in the &lt;a href=&quot;#create-a-connection-to-the-basyx-aas-server&quot;&gt;connection between Ditto and the BaSyx AAS Server&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With this mapping, it is now possible to configure a new connection from Ditto to a BaSyx AAS registry through the following HTTP request:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl &lt;span class=&quot;nt&quot;&gt;-X&lt;/span&gt; POST &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; devops:foobar &lt;span class=&quot;nt&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Content-Type: application/json&apos;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--data-binary&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;{
    &quot;targetActorSelection&quot;: &quot;/system/sharding/connection&quot;,
    &quot;headers&quot;: {
      &quot;aggregate&quot;: false
    },
    &quot;piggybackCommand&quot;: {
      &quot;type&quot;: &quot;connectivity.commands:createConnection&quot;,
      &quot;connection&quot;: {
        &quot;id&quot;: &quot;basyxregistry-http-connection&quot;,
        &quot;connectionType&quot;: &quot;http-push&quot;,
        &quot;connectionStatus&quot;: &quot;open&quot;,
        &quot;uri&quot;: &quot;&amp;lt;basyx-registry-instance-url&amp;gt;:4000&quot;,
        &quot;failoverEnabled&quot;: true,
        &quot;mappingDefinitions&quot;: {
          &quot;mappingforShell&quot;: {
            &quot;mappingEngine&quot;: &quot;JavaScript&quot;,
            &quot;options&quot;: {
              &quot;outgoingScript&quot;: &quot;function mapFromDittoProtocolMsg(namespace, name, group, channel, criterion, action, path, dittoHeaders, value, status, extra) {\n  let headers = dittoHeaders;\n  let textPayload = JSON.stringify({\n    endpoints: [\n        {\n            address: &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;&amp;lt;basyx-server-instance-url&amp;gt;:4001/aasServer/shells/&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos; + namespace + &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;/aas&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;,\n            type: &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;http&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;\n        }\n    ],\n    modelType: {\n        name: &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;AssetAdministrationShellDescriptor&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;\n    },\n    identification: {\n        idType: &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;Custom&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;,\n        id: namespace\n},\n    idShort: namespace,\n      asset: {\n          identification: {\n              idType: &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;Custom&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;,\n              id: namespace + &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;-asset&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;\n          },\n          idShort: namespace + &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;-asset&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;,\n          kind: &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;Instance&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;,\n          dataSpecification: [],\n          modelType: {\n              name: &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;Asset&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;\n          },\n          embeddedDataSpecifications: []\n      },\n      submodels: []\n  });\n  let bytePayload = null;\n  let contentType = &apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;application/json&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;;\n  return Ditto.buildExternalMsg(headers, textPayload, bytePayload, contentType);}&quot;
            }
          }
        },
        &quot;sources&quot;: [],
        &quot;targets&quot;: [
          {
            &quot;address&quot;: &quot;PUT:/registry/api/v1/registry/{{ thing:namespace }}&quot;,
            &quot;headerMapping&quot;: {
              &quot;content-type&quot;: &quot;{{ header:content-type }}&quot;
            },
            &quot;authorizationContext&quot;: [&quot;nginx:ditto&quot;],
            &quot;topics&quot;: [
              &quot;_/_/things/twin/events?filter=and(in(topic:action,&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;created&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;),eq(resource:path,&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;/&apos;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;))&quot;
            ],
            &quot;payloadMapping&quot;: [
              &quot;mappingforShell&quot;
            ]
          }
        ]
      }
    }
  }&apos;&lt;/span&gt; &amp;lt;ditto-instance-url&amp;gt;/devops/piggyback/connectivity
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Listing 7: Request to add a new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Connection&lt;/code&gt; to a Ditto instance&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We list the JavaScript mapper in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;piggybackCommand.connection.mappingDefinitions.mappingForShell.options.outgoingScript&lt;/code&gt; and reference it as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mappingForShell&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;piggybackCommand.connection.targets[0].payloadMapping&lt;/code&gt;.
The address of the BaSyx AAS registry is configured in the parameter &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;piggybackCommand.connection.uri&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As filter, to make sure that our mapper function only triggers after the creation of new Thing, we use:&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s2&quot;&gt;&quot;_/_/things/twin/events?filter=and(in(topic:action,&apos;&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&apos;created&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;),eq(resource:path,&apos;&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&apos;))&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Since the registry uses the AAS server endpoint as a base to also get access to all submodels and submodel elements from the same AAS, it is enough to register the AAS endpoint.&lt;/p&gt;

&lt;h3 id=&quot;test-the-connection&quot;&gt;Test the Connection&lt;/h3&gt;

&lt;p&gt;We now configured all required connections in Ditto and can test our setup.
All configured mappers trigger through changes to a Thing, so we begin by creating a Thing.&lt;/p&gt;

&lt;p&gt;We again refer to the used Ditto instance through the placeholder &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;ditto-instance-url&amp;gt;&lt;/code&gt;,
which you need to adapt to the URL of your Ditto instance.&lt;/p&gt;

&lt;h4 id=&quot;creating-a-thing-in-eclipse-ditto&quot;&gt;Creating a Thing in Eclipse Ditto&lt;/h4&gt;

&lt;h5 id=&quot;setup-a-common-policy&quot;&gt;Setup a common policy&lt;/h5&gt;

&lt;p&gt;To define authorization information to be used by the Things,
we first create a &lt;a href=&quot;basic-policy.html&quot;&gt;policy&lt;/a&gt; with the policy-id &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;machine:my-policy&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;POLICY_ID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;machine:my-policy

curl &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-X&lt;/span&gt; PUT &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; ditto:ditto &lt;span class=&quot;nt&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Content-Type: application/json&apos;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--data&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;{
  &quot;entries&quot;: {
    &quot;DEFAULT&quot;: {
      &quot;subjects&quot;: {
        &quot;{{ request:subjectId }}&quot;: {
           &quot;type&quot;: &quot;Ditto user authenticated via nginx&quot;
        }
      },
      &quot;resources&quot;: {
        &quot;thing:/&quot;: {
          &quot;grant&quot;: [&quot;READ&quot;, &quot;WRITE&quot;],
          &quot;revoke&quot;: []
        },
        &quot;policy:/&quot;: {
          &quot;grant&quot;: [&quot;READ&quot;, &quot;WRITE&quot;],
          &quot;revoke&quot;: []
        },
        &quot;message:/&quot;: {
          &quot;grant&quot;: [&quot;READ&quot;, &quot;WRITE&quot;],
          &quot;revoke&quot;: []
        }
      }
    }
  }
}&apos;&lt;/span&gt; &amp;lt;ditto-instance-url&amp;gt;/api/2/policies/&lt;span class=&quot;nv&quot;&gt;$POLICY_ID&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Listing 8: Demo Policy Definition&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You will get a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;201 Created&lt;/code&gt; response, if the policy creation concluded successfuly. In the subsequent steps, we use the policy-id &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;machine:my-policy&lt;/code&gt; to refer to the created policy.&lt;/p&gt;

&lt;h4 id=&quot;create-a-thing&quot;&gt;Create a Thing&lt;/h4&gt;

&lt;p&gt;The next step is to create an actual Thing.
We use the namespace and name &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;machine:my-policy&lt;/code&gt; and policy-id &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;machine:my-policy&lt;/code&gt; here:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;NAMESPACE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;machine
&lt;span class=&quot;nv&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;sensor
&lt;span class=&quot;nv&quot;&gt;DEVICE_ID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$NAMESPACE&lt;/span&gt;:&lt;span class=&quot;nv&quot;&gt;$NAME&lt;/span&gt;

curl &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-X&lt;/span&gt; PUT &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; ditto:ditto &lt;span class=&quot;nt&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Content-Type: application/json&apos;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--data&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;{
  &quot;policyId&quot;: &quot;&apos;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$POLICY_ID&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;&quot;
}&apos;&lt;/span&gt; &amp;lt;ditto-instance-url&amp;gt;/api/2/things/&lt;span class=&quot;nv&quot;&gt;$DEVICE_ID&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Listing 9: Request to add the Demo Policy to a Ditto instance (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$POLICY_ID&lt;/code&gt; refers to Listing 8)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Again, a successful creation returns a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;201 Created&lt;/code&gt; response.&lt;/p&gt;

&lt;p&gt;We earlier configured two connections to trigger a mapper on the create event of a Thing. This should push a new AAS to the AAS server and a reference to that AAS in the AAS registry.&lt;/p&gt;

&lt;p&gt;You can check whether the execution of the scripts was successful by requesting the shell at the AAS server:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl &lt;span class=&quot;nt&quot;&gt;-X&lt;/span&gt; GET &amp;lt;basyx-server-instance-url&amp;gt;:4001/aasServer/shells
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;which should return the following result&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;modelType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;AssetAdministrationShell&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;idShort&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;machine&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;identification&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;idType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Custom&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;machine&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;dataSpecification&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[],&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;embeddedDataSpecifications&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[],&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;submodels&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;keys&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;AssetAdministrationShell&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;local&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;machine&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;idType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Custom&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Submodel&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;local&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;sensor_temperature&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;idType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Custom&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}]}],&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;asset&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;keys&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Asset&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;local&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;machine-asset&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;idType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Custom&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}],&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;identification&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;idType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Custom&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;machine-asset&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;idShort&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;machine-asset&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;kind&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Instance&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;dataSpecification&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[],&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;modelType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Asset&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;embeddedDataSpecifications&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[]},&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;views&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[],&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;conceptDictionary&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[]}]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In addition, the request to the AAS registry:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl &lt;span class=&quot;nt&quot;&gt;-X&lt;/span&gt; GET &amp;lt;basyx-registry-instance-url&amp;gt;:4000/registry/api/v1/registry
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;should return:&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;modelType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;AssetAdministrationShellDescriptor&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;endpoints&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;address&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&amp;lt;basyx-server-instance-url&amp;gt;:4001/aasServer/shells/machine/aas&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;http&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}],&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;identification&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;idType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Custom&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;machine&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;idShort&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;machine&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;asset&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;identification&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;idType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Custom&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;machine-asset&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;idShort&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;machine-asset&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;kind&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Instance&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;dataSpecification&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[],&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;modelType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Asset&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;embeddedDataSpecifications&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[]},&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;submodels&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[]}]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;At this point, the newly created Thing has no features, properties, or attributes yet.
So let us populate that Thing.&lt;/p&gt;

&lt;h4 id=&quot;create-a-feature-for-the-thing&quot;&gt;Create a feature for the Thing&lt;/h4&gt;

&lt;p&gt;Next, we create a feature for the Thing to contain a property with the data of a temperature sensor.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;FEATURE_ID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;temperature

curl &lt;span class=&quot;nt&quot;&gt;-X&lt;/span&gt; PUT &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; ditto:ditto &lt;span class=&quot;nt&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Content-Type: application/json&apos;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--data-binary&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;{
  &quot;properties&quot;: {
    &quot;value&quot;: null
  }
}&apos;&lt;/span&gt; &amp;lt;ditto-instance-url&amp;gt;/api/2/things/&lt;span class=&quot;nv&quot;&gt;$DEVICE_ID&lt;/span&gt;/features/&lt;span class=&quot;nv&quot;&gt;$FEATURE_ID&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Listing 10: Request to add a feature to the demo Thing (variables refer to previous Listings)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The feature creation triggers the mapper (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mappingforSubmodel&lt;/code&gt;) to create a corresponding Submodel in the previously created AAS.&lt;/p&gt;

&lt;p&gt;To check if this was successful, we request the expected submodel:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl &lt;span class=&quot;nt&quot;&gt;-X&lt;/span&gt; GET &amp;lt;basyx-server-instance-url&amp;gt;:4001/aasServer/shells/&lt;span class=&quot;nv&quot;&gt;$NAMESPACE&lt;/span&gt;/aas/submodels/&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;_&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;FEATURE_ID&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;/submodel
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;which should result in the following response:&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;parent&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;keys&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;idType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Custom&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;AssetAdministrationShell&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;machine&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;local&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}]},&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;identification&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;idType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Custom&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;sensor_temperature&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;idShort&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;sensor_temperature&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;kind&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Instance&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;dataSpecification&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[],&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;modelType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Submodel&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;embeddedDataSpecifications&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[],&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;submodelElements&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[]}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;updating-a-thing&quot;&gt;Updating a Thing&lt;/h4&gt;

&lt;p&gt;After we have successfully created a Thing, we can check if the update of a property works as well by executing:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-X&lt;/span&gt; PUT &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; ditto:ditto &lt;span class=&quot;nt&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;content-type: application/json&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--data-binary&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;46&apos;&lt;/span&gt; &amp;lt;ditto-instance-url&amp;gt;/api/2/things/&lt;span class=&quot;nv&quot;&gt;$DEVICE_ID&lt;/span&gt;/features/&lt;span class=&quot;nv&quot;&gt;$FEATURE_ID&lt;/span&gt;/properties/value
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Again, we check if our change was successful:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; ditto:ditto &lt;span class=&quot;nt&quot;&gt;-w&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;\n&apos;&lt;/span&gt; &amp;lt;ditto-instance-url&amp;gt;/api/2/things/&lt;span class=&quot;nv&quot;&gt;$DEVICE_ID&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and expect:&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;thingId&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;machine:sensor&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;policyId&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;machine:my-policy&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;features&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;temperature&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;properties&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;46&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}}}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If the property creation was successful, then the mapping &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mappingforSubmodelElement&lt;/code&gt; should trigger.
To verify that the Submodel was updated, call:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl &lt;span class=&quot;nt&quot;&gt;-X&lt;/span&gt; GET &amp;lt;basyx-server-instance-url&amp;gt;:4001/aasServer/shells/&lt;span class=&quot;nv&quot;&gt;$NAMESPACE&lt;/span&gt;/aas/submodels/&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;_&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;FEATURE_ID&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;/submodel/submodelElements/properties_value
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This should lead to the response:&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;parent&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;keys&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;idType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Custom&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Submodel&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;sensor_temperature&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;local&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}]},&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;idShort&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;properties_value&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;kind&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Instance&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;valueType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;int&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;modelType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Property&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;46&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here, we see that we are able to access the sensor data of the device through the AAS Submodel API via Eclipse BaSyx.&lt;/p&gt;

&lt;p&gt;As an alternative to plain Json responses, you can use one of the UI-tools provided by the AAS community, like the &lt;a href=&quot;https://wiki.eclipse.org/BaSyx_/_Documentation_/_Components_/_AAS_Web_UI&quot;&gt;AAS Web UI&lt;/a&gt;.&lt;/p&gt;

&lt;figure&gt;&lt;img class=&quot;docimage&quot; src=&quot;images/blog/2024-02-15-integrating-ditto-ass-basyx/AASDashboard.png&quot; alt=&quot;AAS Dashboard&quot; style=&quot;max-width: 1000px&quot; /&gt;&lt;/figure&gt;

&lt;p&gt;&lt;em&gt;Figure 4: BaSyx AAS Web UI&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;In this post, we present our approach for making Ditto Things available in an AAS.
We defined a mapping concept between Things and AAS.
To apply the mapping concept, we created connections with mappers from Ditto to a BaSyx AAS server and a BaSyx AAS registry.
Afterwards, we tested the connections with an example Thing and data from a sensor.&lt;/p&gt;

&lt;p&gt;Our example of integrating Ditto Things into an AAS environment shows, how the capbilities of Ditto, such as
custom mappers, filters etc, render it a useful tool to integrate device states into various environments.
We discussed the integration into AAS but believe a similar approach could be applied in other domains as well.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;br /&gt;
Milena Jäntgen, &lt;a href=&quot;https://github.com/eriksven&quot;&gt;Sven Erik Jeroschewski&lt;/a&gt; and &lt;a href=&quot;https://github.com/max-grzanna&quot;&gt;Max Grzanna&lt;/a&gt; contributed to this post.&lt;/p&gt;
</description>
            <pubDate>Tue, 27 Feb 2024 00:00:00 +0000</pubDate>
            <link>https://www.eclipse.dev/ditto/2024-02-27-integrating-ditto-aas-basyx.html</link>
            <guid isPermaLink="true">https://www.eclipse.dev/ditto/2024-02-27-integrating-ditto-aas-basyx.html</guid>
            
            <category>blog</category>
            
            
        </item>
        
        <item>
            <title>Announcing Eclipse Ditto Release 3.5.0</title>
            <description>&lt;p&gt;The Eclipse Ditto team wished you a happy new year and is excited to announce availability of Ditto
&lt;a href=&quot;https://projects.eclipse.org/projects/iot.ditto/releases/3.5.0&quot;&gt;3.5.0&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In 3.5.0 a lot of UI improvements are contained and several smaller but very useful features were added.&lt;br /&gt;
Thanks a lot to the contributors who contributed to this release, this is really appreciated.&lt;/p&gt;

&lt;h2 id=&quot;adoption&quot;&gt;Adoption&lt;/h2&gt;

&lt;p&gt;Companies are willing to show their adoption of Eclipse Ditto publicly: 
&lt;a href=&quot;https://iot.eclipse.org/adopters/?#iot.ditto&quot;&gt;https://iot.eclipse.org/adopters/?#iot.ditto&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you use Eclipse Ditto it would be great to support the project by putting your logo there.&lt;/p&gt;

&lt;h2 id=&quot;changelog&quot;&gt;Changelog&lt;/h2&gt;

&lt;p&gt;The main improvements and additions of Ditto 3.5.0 are:&lt;/p&gt;

&lt;p&gt;Eclipse Ditto 3.5.0 focuses on the following areas:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Search in the history&lt;/strong&gt; of a &lt;strong&gt;single thing&lt;/strong&gt; using an RQL filter&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Configure per namespace&lt;/strong&gt; the &lt;strong&gt;fields to index&lt;/strong&gt; in Ditto’s &lt;strong&gt;search index&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Configure &lt;strong&gt;defined search count queries&lt;/strong&gt; to be &lt;strong&gt;exposed as Prometheus metrics&lt;/strong&gt; by Ditto periodically&lt;/li&gt;
  &lt;li&gt;Providing &lt;strong&gt;new placeholder functionality&lt;/strong&gt; to the &lt;strong&gt;time placeholder&lt;/strong&gt;, being able to &lt;strong&gt;add and subtract to/from
the current time&lt;/strong&gt; and to truncate the time to a given unit&lt;/li&gt;
  &lt;li&gt;Enhance &lt;strong&gt;WoT (Web of Things) JSON skeleton creation&lt;/strong&gt; to be able to &lt;strong&gt;fail with an exception&lt;/strong&gt; on &lt;strong&gt;invalid&lt;/strong&gt; WoT models&lt;/li&gt;
  &lt;li&gt;Provide &lt;strong&gt;negative numbers&lt;/strong&gt; when &lt;strong&gt;querying for the historical events&lt;/strong&gt; of an entity (thing, policy, connection) in order to
&lt;strong&gt;e.g. get “latest 10” events&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;UI enhancements:
    &lt;ul&gt;
      &lt;li&gt;Show &lt;strong&gt;policy imports&lt;/strong&gt; in Ditto explorer UI&lt;/li&gt;
      &lt;li&gt;Enhance UI &lt;strong&gt;Operations&lt;/strong&gt; functionality to be able to &lt;strong&gt;perform devops/piggyback commands&lt;/strong&gt;&lt;/li&gt;
      &lt;li&gt;Allow &lt;strong&gt;editors in UI&lt;/strong&gt; to toggle &lt;strong&gt;full screen mode&lt;/strong&gt;&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;Display attributes in UI&lt;/strong&gt; inside a &lt;strong&gt;JSON editor&lt;/strong&gt; in order to correctly display structured JSON payloads&lt;/li&gt;
      &lt;li&gt;Enhance “&lt;strong&gt;Incoming Thing Updates&lt;/strong&gt;” section by &lt;strong&gt;displaying “Action” and “Path” in the table&lt;/strong&gt; and adding a &lt;strong&gt;dropdown to
select the amount of details&lt;/strong&gt; to show per event&lt;/li&gt;
      &lt;li&gt;Add &lt;strong&gt;client side filter option&lt;/strong&gt; for filtering &lt;strong&gt;Incoming Thing Updates&lt;/strong&gt; and &lt;strong&gt;Connection logs&lt;/strong&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following non-functional work is also included:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Configured docker-compose to by default retain only the last 50m of log messages per Ditto service&lt;/li&gt;
  &lt;li&gt;Migrated SLF4J to version 2.x and logback to version 1.4.x&lt;/li&gt;
  &lt;li&gt;Benchmark tool improvements and fixes&lt;/li&gt;
  &lt;li&gt;Improve cluster stability when running in Kubernetes, e.g. on updates or k8s node-shutdowns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following notable fixes are included:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Fix enriching Thing creation events with the inlined &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_policy&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Fixed that Ditto’s own calculated “health” was not exposed to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/alive&lt;/code&gt; endpoint scraped by Kubernetes to check for
aliveness of single services&lt;/li&gt;
  &lt;li&gt;Fixed that no cache was used when updating the search index when an “imported” policy was modified&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please have a look at the &lt;a href=&quot;release_notes_350.html&quot;&gt;3.5.0 release notes&lt;/a&gt; for a more detailed information on the release.&lt;/p&gt;

&lt;h2 id=&quot;artifacts&quot;&gt;Artifacts&lt;/h2&gt;

&lt;p&gt;The new Java artifacts have been published at the &lt;a href=&quot;https://repo.eclipse.org/content/repositories/ditto/&quot;&gt;Eclipse Maven repository&lt;/a&gt;
as well as &lt;a href=&quot;https://repo1.maven.org/maven2/org/eclipse/ditto/&quot;&gt;Maven central&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The Ditto JavaScript client release was published on &lt;a href=&quot;https://www.npmjs.com/~eclipse_ditto&quot;&gt;npmjs.com&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/@eclipse-ditto/ditto-javascript-client-dom&quot;&gt;@eclipse-ditto/ditto-javascript-client-dom&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/@eclipse-ditto/ditto-javascript-client-node&quot;&gt;@eclipse-ditto/ditto-javascript-client-node&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Docker images have been pushed to Docker Hub:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-policies/&quot;&gt;eclipse/ditto-policies&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-things/&quot;&gt;eclipse/ditto-things&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-things-search/&quot;&gt;eclipse/ditto-things-search&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-gateway/&quot;&gt;eclipse/ditto-gateway&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-connectivity/&quot;&gt;eclipse/ditto-connectivity&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Ditto Helm chart has been published to Docker Hub:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto/&quot;&gt;eclipse/ditto&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;figure&gt;&lt;img class=&quot;docimage&quot; src=&quot;images/ditto.svg&quot; alt=&quot;Ditto&quot; style=&quot;max-width: 500px&quot; /&gt;&lt;/figure&gt;

&lt;p&gt;–&lt;br /&gt;
The Eclipse Ditto team&lt;/p&gt;
</description>
            <pubDate>Fri, 26 Jan 2024 00:00:00 +0000</pubDate>
            <link>https://www.eclipse.dev/ditto/2024-01-26-release-announcement-350.html</link>
            <guid isPermaLink="true">https://www.eclipse.dev/ditto/2024-01-26-release-announcement-350.html</guid>
            
            <category>blog</category>
            
            
        </item>
        
        <item>
            <title>Announcing Eclipse Ditto Release 3.4.0</title>
            <description>&lt;p&gt;The Eclipse Ditto teams is proud to announce the availability of Eclipse Ditto 
&lt;a href=&quot;https://projects.eclipse.org/projects/iot.ditto/releases/3.4.0&quot;&gt;3.4.0&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Version 3.4.0 mainly concentrates on exchanging the use of the &lt;a href=&quot;https://akka.io&quot;&gt;Akka toolkit&lt;/a&gt; 
(due to a change in licensing) with its fork &lt;a href=&quot;https://pekko.apache.org/&quot;&gt;Apache Pekko&lt;/a&gt; which remains Apache 2.0 licensed.&lt;br /&gt;
Apart from that, several improvements are also included which can be found in the changelog.&lt;/p&gt;

&lt;h2 id=&quot;adoption&quot;&gt;Adoption&lt;/h2&gt;

&lt;p&gt;Companies are willing to show their adoption of Eclipse Ditto publicly: 
&lt;a href=&quot;https://iot.eclipse.org/adopters/?#iot.ditto&quot;&gt;https://iot.eclipse.org/adopters/?#iot.ditto&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you use Eclipse Ditto it would be great to support the project by putting your logo there.&lt;/p&gt;

&lt;h2 id=&quot;changelog&quot;&gt;Changelog&lt;/h2&gt;

&lt;p&gt;The main improvements and additions of Ditto 3.4.0 are:&lt;/p&gt;

&lt;p&gt;Eclipse Ditto 3.4.0 focuses on the following areas:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Supporting &lt;strong&gt;HTTP &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;POST&lt;/code&gt;&lt;/strong&gt; for performing &lt;strong&gt;searches&lt;/strong&gt; with a very &lt;strong&gt;long query&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Addition of a &lt;strong&gt;new placeholder&lt;/strong&gt; to use &lt;strong&gt;in connections&lt;/strong&gt; to use &lt;strong&gt;payload of the thing JSON&lt;/strong&gt; e.g. in headers or addresses&lt;/li&gt;
  &lt;li&gt;New &lt;strong&gt;placeholder functions&lt;/strong&gt; for &lt;strong&gt;joining&lt;/strong&gt; multiple elements into a single string and doing &lt;strong&gt;URL-encoding and -decoding&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Configure &lt;strong&gt;MQTT message expiry interval for published messages&lt;/strong&gt; via a header&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Reduce patch/merge thing commands&lt;/strong&gt; to &lt;strong&gt;modify&lt;/strong&gt; only the &lt;strong&gt;actually changed values&lt;/strong&gt; with a new option&lt;/li&gt;
  &lt;li&gt;UI enhancements:
    &lt;ul&gt;
      &lt;li&gt;Adding sending messages to Things&lt;/li&gt;
      &lt;li&gt;Made UI (at least navigation bar) responsive for small screen sizes&lt;/li&gt;
      &lt;li&gt;Increase size of JSON editors in “edit” mode&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following non-functional work is also included:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Swapping the &lt;a href=&quot;https://akka.io&quot;&gt;Akka toolkit&lt;/a&gt;&lt;/strong&gt; (because of its switch of license to &lt;a href=&quot;https://www.lightbend.com/akka/license-faq&quot;&gt;BSL License&lt;/a&gt; after Akka v2.6.x)
&lt;strong&gt;with its fork &lt;a href=&quot;https://pekko.apache.org/&quot;&gt;Apache Pekko&lt;/a&gt;&lt;/strong&gt; which remains Apache 2.0 licensed.&lt;/li&gt;
  &lt;li&gt;Support for using &lt;strong&gt;AWS DocumentDB&lt;/strong&gt; as a replacement for MongoDB&lt;/li&gt;
  &lt;li&gt;Improve logging by adding the &lt;strong&gt;W3C Trace Context&lt;/strong&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;traceparent&lt;/code&gt; header as MDC field to logs&lt;/li&gt;
  &lt;li&gt;Adjust handling of special MQTT headers in MQTT 5&lt;/li&gt;
  &lt;li&gt;Optimize docker files&lt;/li&gt;
  &lt;li&gt;Migration of Ditto UI to TypeScript&lt;/li&gt;
  &lt;li&gt;There now is an official &lt;strong&gt;&lt;a href=&quot;2023-10-09-ditto-benchmark.html&quot;&gt;Eclipse Ditto Benchmark&lt;/a&gt;&lt;/strong&gt; which shows how Ditto is able
to scale horizontally and provides some tuning tips&lt;/li&gt;
  &lt;li&gt;Addition of a &lt;strong&gt;benchmark tooling&lt;/strong&gt; to run own Ditto benchmarks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following notable fixes are included:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Fixed that failed retrieval of a policy (e.g. after policy change) leads to search index being “emptied out”&lt;/li&gt;
  &lt;li&gt;Fixed that putting metadata when updating a single scalar value did not work&lt;/li&gt;
  &lt;li&gt;UI fix, fixing that patching a thing will null values did not reflect that change in the UI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please have a look at the &lt;a href=&quot;release_notes_340.html&quot;&gt;3.4.0 release notes&lt;/a&gt; for a more detailed information on the release.&lt;/p&gt;

&lt;h2 id=&quot;artifacts&quot;&gt;Artifacts&lt;/h2&gt;

&lt;p&gt;The new Java artifacts have been published at the &lt;a href=&quot;https://repo.eclipse.org/content/repositories/ditto/&quot;&gt;Eclipse Maven repository&lt;/a&gt;
as well as &lt;a href=&quot;https://repo1.maven.org/maven2/org/eclipse/ditto/&quot;&gt;Maven central&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The Ditto JavaScript client release was published on &lt;a href=&quot;https://www.npmjs.com/~eclipse_ditto&quot;&gt;npmjs.com&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/@eclipse-ditto/ditto-javascript-client-dom&quot;&gt;@eclipse-ditto/ditto-javascript-client-dom&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/@eclipse-ditto/ditto-javascript-client-node&quot;&gt;@eclipse-ditto/ditto-javascript-client-node&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Docker images have been pushed to Docker Hub:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-policies/&quot;&gt;eclipse/ditto-policies&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-things/&quot;&gt;eclipse/ditto-things&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-things-search/&quot;&gt;eclipse/ditto-things-search&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-gateway/&quot;&gt;eclipse/ditto-gateway&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto-connectivity/&quot;&gt;eclipse/ditto-connectivity&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Ditto Helm chart has been published to Docker Hub:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/eclipse/ditto/&quot;&gt;eclipse/ditto&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;figure&gt;&lt;img class=&quot;docimage&quot; src=&quot;images/ditto.svg&quot; alt=&quot;Ditto&quot; style=&quot;max-width: 500px&quot; /&gt;&lt;/figure&gt;

&lt;p&gt;–&lt;br /&gt;
The Eclipse Ditto team&lt;/p&gt;
</description>
            <pubDate>Tue, 17 Oct 2023 00:00:00 +0000</pubDate>
            <link>https://www.eclipse.dev/ditto/2023-10-17-release-announcement-340.html</link>
            <guid isPermaLink="true">https://www.eclipse.dev/ditto/2023-10-17-release-announcement-340.html</guid>
            
            <category>blog</category>
            
            
        </item>
        
    </channel>
</rss>
