> For the complete documentation index, see [llms.txt](https://docs.cybus.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.cybus.io/2-4-2/guides/system-connectivity/mes-erp-business-systems/heisenware-integration.md).

# Heisenware Integration

This guide describes how to integrate the Heisenware low-code app building platform with Connectware. Heisenware connects to the Connectware MQTT broker with its MQTT Client connector, subscribes to Unified Namespace (UNS) topics to feed dashboards and operator apps, and publishes operator inputs back into the topic hierarchy. A complete example file is available at the end of this guide.

## Objectives

* Creating a Connectware user and role that Heisenware uses to authenticate against the Connectware MQTT broker.
* Connecting the Heisenware MQTT Client connector to the Connectware broker.
* Subscribing to UNS topics to feed Heisenware dashboards and operator apps.
* Publishing operator inputs from Heisenware and routing them into the topic hierarchy with a mapping.

## Prerequisites

To follow this guide, you will need the following:

* A running instance of Cybus Connectware.
* A Heisenware workspace with access to the Heisenware App Builder. For more information, see the [Heisenware documentation](https://docs.heisenware.com).
* Network access from the Heisenware backend to the Connectware MQTT broker port, `8883` by default. If your Heisenware workspace runs in the Heisenware cloud, the Connectware broker must be reachable from outside your network.
* Access to the [Admin UI](/2-4-2/access/admin-ui.md) with sufficient [user permissions](/2-4-2/access/user-management.md).
* Basic knowledge of MQTT and the Connectware [services](/2-4-2/data-flows/services.md) concept (for example, [service commissioning files](/2-4-2/data-flows/service-commissioning-files.md), [users](/2-4-2/data-flows/service-commissioning-files/resources/cybus-user.md), [roles](/2-4-2/data-flows/service-commissioning-files/resources/cybus-role.md), and [mappings](/2-4-2/data-flows/service-commissioning-files/resources/cybus-mapping.md)).
* It helps to be familiar with [Connecting an MQTT Client to Publish and Subscribe Data](/2-4-2/guides/machine-connectivity/gateways-generic-protocols/connecting-an-mqtt-client-to-publish-and-subscribe-data.md).

## Connectware and Heisenware Integration

Heisenware is a low-code platform for building industrial applications, such as shop floor dashboards, operator apps, and monitoring tools. You assemble the backend logic from functions on a canvas and connect the function outputs to UI widgets. The function catalog includes the [MQTT Client connector](https://docs.heisenware.com/app-builder/build-backend/functions/connectors/mqtt-client), an `MqttClient` class that manages client connections to an MQTT broker over TCP, TLS, and WebSockets.

The integration uses this connector in both directions:

* **Consuming UNS data**: Heisenware connects out to the Connectware broker and subscribes to the UNS topics that the dashboard or operator app displays. Connectware remains the central broker, so no inbound firewall port to Heisenware is required, and Heisenware sees the same governed data as every other consumer.
* **Producing operator inputs**: Heisenware apps publish operator inputs, such as a setpoint or an order confirmation, to a dedicated `heisenware` namespace. A Connectware mapping routes these messages into the topic hierarchy, so you control what enters the UNS and can validate or transform the messages on the way.

The only Connectware-side preparation is a user with scoped permissions and the routing mapping, both defined in a service commissioning file. The rest of the integration is configured in the Heisenware App Builder.

The MQTT topics in this guide follow an ISA-95-style equipment hierarchy (`<enterprise>/<site>/<area>/<line>/<cell>`). Adjust the topic filters and permissions to your own hierarchy.

{% hint style="info" %}
Heisenware also provides an [HTTP/REST connector](https://docs.heisenware.com/app-builder/build-backend/functions/connectors/http-rest) that can call REST APIs, for example a route hosted by the Connectware [HTTP Server](/2-4-2/connectors/servers/http-server.md). This guide focuses on MQTT, which fits streaming dashboard data best.
{% endhint %}

## Creating a Connectware User for Heisenware

The Heisenware MQTT client authenticates against the Connectware broker with username and password, like any other MQTT client. For more information, see [MQTT Client Authentication](/2-4-2/access/user-management/mqtt-user-authentication.md). We create the user and its role in the service commissioning file with the [Cybus::User](/2-4-2/data-flows/service-commissioning-files/resources/cybus-user.md) and [Cybus::Role](/2-4-2/data-flows/service-commissioning-files/resources/cybus-role.md) resources.

Do not worry about copying the service commissioning file snippets together into one, the complete example file is available at the end of this guide.

### Integration Parameters

We add the password of the MQTT user and the UNS topic root as parameters, so you can set them when you install the service:

* `heisenwarePassword`: The password that Heisenware uses to authenticate.
* `topicRoot`: The root of the UNS topic hierarchy. Defaults to `enterprise`.

{% code lineNumbers="true" %}

```yaml
parameters:
  heisenwarePassword:
    description: Password of the MQTT user that Heisenware uses to authenticate
    type: string

  topicRoot:
    description: Root of the UNS topic hierarchy
    type: string
    default: enterprise
```

{% endcode %}

### Heisenware User and Role

The role follows the principle of least privilege: Heisenware reads the whole UNS hierarchy for its dashboards and writes only into its own `heisenware` namespace. The `read` operation is equivalent to MQTT subscribe, the `write` operation to MQTT publish. For more information, see [Permissions](/2-4-2/access/user-management/permissions.md).

{% code lineNumbers="true" %}

```yaml
resources:
  heisenwareRole:
    type: Cybus::Role
    properties:
      permissions:
        - resource: !sub '${topicRoot}/#'
          operation: read
          context: mqtt
        - resource: heisenware/#
          operation: write
          context: mqtt

  app:
    type: Cybus::User
    properties:
      password: !ref heisenwarePassword
      roles:
        - !ref heisenwareRole
```

{% endcode %}

The resource identifier of the user becomes the username, prefixed with the [service ID](/2-4-2/data-flows/services/serviceid.md) that you assign when you install the service. For example, with the service ID `heisenware`, the Heisenware app authenticates as `heisenware.app`.

{% hint style="info" %}
Instead of defining the user in the service commissioning file, you can also create it in the Admin UI: click **User** on the navigation panel, add a user, and assign the same MQTT permissions in the Add Permissions panel. In that case, the username has no service ID prefix.
{% endhint %}

## Connecting Heisenware to Connectware

You configure the Heisenware side in the App Builder. The following steps describe the workflow at a high level. For the complete function reference, see the [MQTT Client connector](https://docs.heisenware.com/app-builder/build-backend/functions/connectors/mqtt-client) in the Heisenware documentation.

### Creating the MQTT Client Instance

1. In the Heisenware App Builder, open the **Function Explorer** and browse to the **Connectors** category.
2. Drag the **MQTT Client** connector onto the canvas.
3. Call the `create` function and set an instance name, for example `connectware`.
4. Call the `connect` function of the new instance. Set the `url` argument to `mqtts://${CONNECTWARE_HOST}:8883` and pass the credentials in the options object: set `username` to the Connectware user, for example `heisenware.app`, and `password` to the value of the `heisenwarePassword` parameter.

Replace the following value:

* `${CONNECTWARE_HOST}`: The hostname or IP address of your Connectware instance.

The `connect` function returns `true` once the connection is established. Use the `isConnected` function to check the connection state at any time.

The `mqtts://` scheme connects with TLS. The Heisenware backend must trust the server certificate of your Connectware instance. If Connectware uses a self-signed certificate, replace it with a certificate that is signed by a certificate authority that the Heisenware backend trusts. For more information, see [CA Certificates](/2-4-2/access/security/tls-certificates/ca-certificates.md). For unencrypted test setups, you can use `mqtt://${CONNECTWARE_HOST}:1883` instead. Use TLS on port `8883` for production.

{% hint style="info" %}
Heisenware provides a pre-configured instance named `internal-mqtt` that is connected to the internal broker of the Heisenware platform. Do not use this instance for the Connectware integration. Create a separate instance that connects to the Connectware broker.
{% endhint %}

### Subscribing to UNS Topics

The `onJsonMessage` function subscribes to a topic filter and handles incoming messages in one step. The listener fires for every message, parses the payload as JSON, and provides the source topic in the `__topic__` attribute of the data object:

1. Call the `onJsonMessage` function of the `connectware` instance.
2. Set the topic filter to the part of the UNS that the app displays, for example `enterprise/hamburg/assembly/line-1/#`. The MQTT wildcards `+` (single level) and `#` (multi-level) are supported.
3. Connect the listener output to a display widget, such as a chart or a value box.

Subscribe as narrowly as the app allows. A dashboard that shows one production line does not need `enterprise/#`, and smaller subscriptions keep the message load in the Heisenware app low.

A Connectware endpoint publishes its values in a JSON structure that the listener parses directly. For example, a temperature reading on the topic `enterprise/hamburg/assembly/line-1/press-01/temperature` arrives with a payload like the following:

{% code lineNumbers="true" %}

```json
{
  "timestamp": 1727215043878,
  "value": 42.1
}
```

{% endcode %}

### Publishing Operator Inputs

Operator apps write data back, for example a setpoint that a worker enters in a form. Use the `publishJson` function, which serializes a JSON object and publishes it to a topic:

1. Call the `publishJson` function of the `connectware` instance from your app logic, for example triggered by a button widget.
2. Set the topic to the `heisenware` namespace, mirroring the equipment hierarchy, for example `heisenware/hamburg/assembly/line-1/press-01/operator-input`.
3. Pass the operator input as the message object.

A published message looks like the following:

{% code lineNumbers="true" %}

```json
{
  "command": "set-target-speed",
  "value": 1200,
  "operator": "shift-a"
}
```

{% endcode %}

The Heisenware user has write permission only on the `heisenware/#` namespace, so a misconfigured app cannot publish into the UNS directly.

## Routing Operator Inputs into the UNS

A mapping republishes the operator inputs from the `heisenware` namespace into the UNS hierarchy. The named wildcard `#topic` matches the remainder of the topic path and reuses it in the output topic as `$topic`:

{% code lineNumbers="true" %}

```yaml
operatorInputMapping:
  type: Cybus::Mapping
  properties:
    mappings:
      - subscribe:
          topic: 'heisenware/#topic'
        publish:
          topic: !sub '${topicRoot}/$topic'
```

{% endcode %}

A message published to `heisenware/hamburg/assembly/line-1/press-01/operator-input` now arrives on `enterprise/hamburg/assembly/line-1/press-01/operator-input`, where any other Connectware service can pick it up, for example to write the setpoint to a PLC.

This mapping is the single point where Heisenware data enters the UNS. To validate or reshape the messages before they are republished, add `filter` or `transform` rules to the mapping. For more information, see [Data Processing Rules](/2-4-2/data-flows/rule-engine/data-processing-rules.md) and [Cybus::Mapping](/2-4-2/data-flows/service-commissioning-files/resources/cybus-mapping.md).

## Verifying the Integration

1. Install the service commissioning file, assign a service ID, for example `heisenware`, and set the `heisenwarePassword` parameter. See [Installing Services](/2-4-2/data-flows/services/managing/installing.md).
2. In the Heisenware App Builder, call the `connect` function and check that it returns `true`. If the connection fails, check the broker URL, the port, the certificate settings, and the credentials. Remember that the username carries the service ID prefix, for example `heisenware.app`.
3. Publish a test message to a UNS topic that the app subscribes to, for example `enterprise/hamburg/assembly/line-1/press-01/temperature`, with an MQTT client or the Admin UI. Check that the connected widget in Heisenware shows the value.
4. Trigger an operator input in the Heisenware app.
5. Open the [Data Explorer](/2-4-2/monitoring/data-explorer.md) and check the message on the `heisenware` namespace and its republished copy in the UNS hierarchy, for example on `enterprise/hamburg/assembly/line-1/press-01/operator-input`.

## Service Commissioning File Example

{% file src="/files/LqamHDQ6U7j3HRJdUZJA" %}

{% code title="heisenware-example.yml" lineNumbers="true" expandable="true" %}

```yaml
---
# ----------------------------------------------------------------------------
# Service Commissioning File
# ----------------------------------------------------------------------------
# Copyright: Cybus GmbH
# Contact: support@cybus.io
# ----------------------------------------------------------------------------
# Heisenware Integration (Example)
# ----------------------------------------------------------------------------

description: >
  Service commissioning file for the integration between Connectware and the
  Heisenware low-code platform (Example)

metadata:
  name: Heisenware Integration
  provider: cybus
  homepage: https://www.cybus.io
  version: 1.0.0

parameters:
  heisenwarePassword:
    description: Password of the MQTT user that Heisenware uses to authenticate
    type: string

  topicRoot:
    description: Root of the UNS topic hierarchy
    type: string
    default: enterprise

resources:
  # Limits Heisenware to reading the UNS hierarchy and writing to its
  # own namespace
  heisenwareRole:
    type: Cybus::Role
    properties:
      permissions:
        - resource: !sub '${topicRoot}/#'
          operation: read
          context: mqtt
        - resource: heisenware/#
          operation: write
          context: mqtt

  # MQTT user for the Heisenware MQTT Client connector. The username is
  # prefixed with the service ID, for example heisenware.app
  app:
    type: Cybus::User
    properties:
      password: !ref heisenwarePassword
      roles:
        - !ref heisenwareRole

  # Routes operator inputs from the Heisenware namespace into the UNS
  operatorInputMapping:
    type: Cybus::Mapping
    properties:
      mappings:
        - subscribe:
            topic: 'heisenware/#topic'
          publish:
            topic: !sub '${topicRoot}/$topic'
```

{% endcode %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.cybus.io/2-4-2/guides/system-connectivity/mes-erp-business-systems/heisenware-integration.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
