> 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/migration/migrating-from-united-manufacturing-hub.md).

# Migrating from United Manufacturing Hub

This guide shows you how to migrate the connectivity layer of a United Manufacturing Hub (UMH) installation to Connectware by extracting the protocol converter configuration and translating it into a [service commissioning file](/2-4-2/data-flows/service-commissioning-files.md). UMH configuration is declarative YAML throughout, which makes the translation a good task for an AI assistant. The guide covers both UMH variants: UMH Core (single container with a central configuration file) and the Helm-based UMH Classic stack, which the UMH documentation marks as deprecated. In more detail, the following topics are covered:

* Understanding how UMH concepts map to Connectware resources
* Extracting the configuration from UMH Core or UMH Classic
* Translating the protocol converters into a service commissioning file with an AI assistant
* Reviewing the generated service commissioning file
* Verifying the migrated data points in the [Data Explorer](/2-4-2/monitoring/data-explorer.md)

A complete worked example, from UMH configuration to service commissioning file, is available at the end of this guide.

## Prerequisites

To follow this guide, you will need the following:

* A running instance of Cybus Connectware with licenses for the connectors that replace your UMH protocol converters.
* Access to the UMH Core data volume, or `kubectl` and `helm` access to the UMH Classic cluster.
* Network access from Connectware to the devices that UMH currently polls.
* An AI assistant to translate the configuration. Any capable large language model (LLM) works. [Cybus Connectware GPT](/2-4-2/tools/cybus-connectware-gpt.md) is a ChatGPT assistant that already knows the service commissioning file format.
* Basic knowledge of 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), [connections](/2-4-2/data-flows/service-commissioning-files/resources/cybus-connection.md), and [endpoints](/2-4-2/data-flows/service-commissioning-files/resources/cybus-endpoint.md)).

## How UMH Concepts Map to Connectware

UMH moves data with benthos-umh pipelines: a protocol converter (called a bridge in the UMH Core UI) combines a protocol input, processors that build the Unified Namespace topic, and an output into the Kafka-based UNS. Connectware organizes the same information in resources of a service commissioning file, with an MQTT broker as the UNS:

| UMH concept                             | Connectware resource                                                                                                                                                                      | Notes                                                                                                                                        |
| --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| Protocol converter / bridge             | [Cybus::Connection](/2-4-2/data-flows/service-commissioning-files/resources/cybus-connection.md) + [endpoints](/2-4-2/data-flows/service-commissioning-files/resources/cybus-endpoint.md) | The `input` block becomes the connection; each address or node becomes an endpoint.                                                          |
| Data flow component (DFC)               | [Cybus::Mapping](/2-4-2/data-flows/service-commissioning-files/resources/cybus-mapping.md) with [Rule Engine](/2-4-2/data-flows/rule-engine.md) rules                                     | Kafka-to-Kafka pipelines usually translate to mappings with rules.                                                                           |
| `umh.v1` topic convention               | MQTT topic hierarchy                                                                                                                                                                      | Dot-separated UMH topic segments become slash-separated MQTT topic levels. The `agent.location` hierarchy becomes the topic prefix.          |
| `tag_processor` and Bloblang processors | Rule Engine `transform` rules                                                                                                                                                             | JavaScript and Bloblang logic must be rewritten as JSONata; flag each processor.                                                             |
| `variables` and `{{ .IP }}` templating  | Parameters and definitions with `!sub`                                                                                                                                                    | Direct conceptual equivalent.                                                                                                                |
| Payload `{"timestamp_ms", "value"}`     | Endpoint payload `{"timestamp", "value"}`                                                                                                                                                 | Consumers that expect the UMH shape need a `transform` rule.                                                                                 |
| Embedded Redpanda / Kafka UNS           | Integrated MQTT broker (CybusMQ)                                                                                                                                                          | Kafka-native consumers connect through the [Kafka connector](/2-4-2/connectors/enterprise-connectors/kafka.md) or subscribe to MQTT instead. |
| Management Console (cloud)              | Admin UI and infrastructure as code                                                                                                                                                       | Connectware is managed on-premises; fleet configuration lives in Git and CI/CD.                                                              |

### Mapping Protocol Inputs to Connectors

The following benthos-umh protocol inputs have a native Connectware connector:

| benthos-umh input                                | Connectware connector                                                                                                                                                                                                                        |
| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `opcua`                                          | [OPC UA Client](/2-4-2/connectors/shop-floor-connectors/opc-ua/opc-ua-client.md)                                                                                                                                                             |
| `s7comm`                                         | [Siemens SIMATIC S7](/2-4-2/connectors/shop-floor-connectors/siemens-simatic-s7.md)                                                                                                                                                          |
| `modbus`                                         | [Modbus/TCP](/2-4-2/connectors/shop-floor-connectors/modbus-tcp.md)                                                                                                                                                                          |
| `ethernetip`                                     | [EtherNet/IP](/2-4-2/connectors/shop-floor-connectors/ethernet-ip.md)                                                                                                                                                                        |
| Standard Benthos inputs (MQTT, Kafka, HTTP, SQL) | [MQTT](/2-4-2/connectors/enterprise-connectors/mqtt.md), [Kafka](/2-4-2/connectors/enterprise-connectors/kafka.md), [HTTP/REST](/2-4-2/connectors/enterprise-connectors/http-rest.md), [SQL](/2-4-2/connectors/enterprise-connectors/sql.md) |

The `sensorconnect` input for ifm IO-Link masters and its IODD enrichment have no native counterpart; evaluate a [custom connector](/2-4-2/connectors/custom-connectors.md) for those devices.

{% hint style="info" %}
The `opcua` input of benthos-umh takes browse roots in its `nodeIDs` list and auto-discovers every variable beneath them. Connectware endpoints are declared per data point. Before translating, get the list of actually collected nodes, for example from the UMH topic browser, and expect this to be the main manual effort of an OPC UA migration.
{% endhint %}

### What Does Not Migrate 1:1

| UMH feature                         | Connectware approach                                                                                                                                                                                                                                                                                 |
| ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Historian (TimescaleDB in Classic)  | Connectware is not a historian. Route data to a database with the [InfluxDB](/2-4-2/connectors/enterprise-connectors/influxdb.md), [SQL](/2-4-2/connectors/enterprise-connectors/sql.md), or [MSSQL](/2-4-2/connectors/enterprise-connectors/mssql.md) connector. Historical data does not transfer. |
| Grafana dashboards (Classic)        | Repoint dashboards at the new data store; queries need rewriting if the store changes.                                                                                                                                                                                                               |
| Kafka semantics                     | Consumer groups, offsets, and compaction do not carry over to MQTT. Kafka-native consumers keep working through the [Kafka connector](/2-4-2/connectors/enterprise-connectors/kafka.md).                                                                                                             |
| Data modeling and stream processors | Core data contracts beyond `_raw` and stream processors must be redesigned with Rule Engine rules and structured topics.                                                                                                                                                                             |
| Node-RED flows (Classic)            | Import into the [Node-RED Workbench](/2-4-2/data-flows/node-red-workbench.md); Kafka nodes must be rewired to MQTT topics.                                                                                                                                                                           |
| Management Console features         | Connection probes, device discovery, and cloud fleet management have no single counterpart; monitoring moves to the Admin UI and deployment to Git-based workflows.                                                                                                                                  |

## Extracting the UMH Configuration

### UMH Core

The complete configuration is one YAML file on the data volume of the container. Copy it from the host volume, or directly from the container:

{% code lineNumbers="true" %}

```bash
docker cp ${UMH_CONTAINER}:/data/config.yaml umh-config.yaml
```

{% endcode %}

* `${UMH_CONTAINER}` is the name or ID of the UMH Core container.

The `protocolConverter` and `dataFlow` sections of the file contain everything to translate; the `agent.location` section defines the topic hierarchy.

### UMH Classic

Protocol converters and data flows live as benthos configurations in Kubernetes ConfigMaps in the `united-manufacturing-hub` namespace:

{% code lineNumbers="true" %}

```bash
kubectl get configmaps -n united-manufacturing-hub
kubectl get configmap ${CONFIGMAP_NAME} -n united-manufacturing-hub -o yaml > umh-dataflow.yaml
helm get values united-manufacturing-hub -n united-manufacturing-hub > umh-values.yaml
```

{% endcode %}

* `${CONFIGMAP_NAME}` is the name of a benthos ConfigMap, for example `benthos-1-config`. List all ConfigMaps and collect every benthos configuration, including the ones generated by the Management Console.

## Translating the Configuration with an AI Assistant

{% hint style="warning" %}
UMH configurations contain credentials in plain text, for example OPC UA usernames and passwords in `input` blocks and connection strings in `variables`. Remove all credentials before you paste the configuration into an AI tool, and check the data privacy terms of the tool you use. See also the privacy notes for [Cybus Connectware GPT](/2-4-2/tools/cybus-connectware-gpt.md#data-privacy).
{% endhint %}

Copy the following prompt and attach the extracted YAML:

{% code title="AI translation prompt" lineNumbers="true" expandable="true" %}

```
You are translating a United Manufacturing Hub configuration (umh.yaml from
UMH Core, or benthos ConfigMaps from UMH Classic) into a Cybus Connectware
service commissioning file (YAML). Produce one complete, valid service
commissioning file with description, metadata, parameters, definitions, and
resources.

Structural rules:
- Each protocolConverter (or benthos pipeline) becomes one
  Cybus::Connection built from its "input" block, plus one Cybus::Endpoint
  per address, tag, or node.
- Resolve "{{ .VARIABLE }}" templating against the "variables" section and
  turn every variable into a service parameter.
- Build MQTT topics from the agent.location hierarchy plus the
  protocolConverter location and tag names: dot-separated UMH segments
  become slash-separated topic levels, lowercase kebab-case. Drop the
  "umh.v1" prefix and the "_raw"/"_historian" contract segment, or keep
  the contract as a topic level if downstream consumers depend on it.
- Translate tag_processor and Bloblang processors that only build topics
  into the mapping structure. Processors that reshape payloads become
  JSONata transform rules; include the original code as a comment and flag
  each one. If consumers expect the UMH payload shape
  {"timestamp_ms": ..., "value": ...}, add a transform rule that renames
  "timestamp" to "timestamp_ms".
- Define hosts and credentials as parameters, never hardcoded. Do not
  include any credentials in the output.

Input-specific rules for "modbus" (protocol: Modbus):
- "controller" is a "tcp://host:port" URL. "timeBetweenReads" becomes the
  endpoint interval.
- "unifiedAddresses" entries follow "<name>.<area>.<address>.<type>":
  holding -> fc 3, input -> fc 4, coil -> fc 1, discrete -> fc 2. Use the
  numeric address as-is and flag it: verify the 0- or 1-based convention
  against live values. Map INT16 -> int16BE, UINT16 -> uint16BE,
  INT32 -> int32BE, UINT32 -> uint32BE, FLOAT32 -> floatBE,
  FLOAT64 -> doubleBE, BOOL -> boolean. Legacy "addresses" entries with
  register/address/type/scale fields follow the same mapping; a "scale"
  factor becomes a JSONata transform rule.
- "slaveIDs" with more than one entry: create one endpoint set per slave
  and flag it.

Input-specific rules for "s7comm" (protocol: S7): "tcpDevice" is the host,
port 102, "rack" and "slot" from the input. Addresses like "DB1.DW20"
translate to the Connectware S7 syntax ("DB1,DW20" style); verify the data
type letters against the Connectware S7 connector documentation and flag
every address.

Input-specific rules for "opcua" (protocol: Opcua): "endpoint",
"securityMode", "securityPolicy", "username" map directly. "nodeIDs"
entries are browse roots, not tags: if a list of actually collected nodes
is provided, create one endpoint per node; otherwise flag the converter as
requiring node enumeration. "subscribeEnabled": true maps to OPC UA
subscriptions (samplingInterval from "pollRate").

For any input without a Connectware connector (for example
"sensorconnect"), skip it and list it at the end under "Not migrated".

After the YAML, output a migration report: number of converters and
endpoints translated, all assumptions made, and every flagged item that
needs manual review.

[Attach: umh-config.yaml or the benthos ConfigMaps. Add the list of
collected OPC UA nodes if available.]
```

{% endcode %}

## Reviewing the Generated Service Commissioning File

Work through this checklist before installing:

1. Validate the file structure. The [Cybus Connectware Extension for VS Code](/2-4-2/tools/cybus-connectware-extension-vs-code.md) validates service commissioning files against the official schemas as you edit.
2. Check every connection against the original `input` block: host, port, security settings, and rack and slot for S7.
3. Spot-check translated Modbus addresses against live values; benthos-umh field conventions changed across versions, so record the benthos-umh version alongside the export.
4. Verify that the topic structure matches what downstream consumers expect, including the decision about the `_raw`/`_historian` segment and the payload shape.
5. Review every translated processor against the original Bloblang or JavaScript code.
6. Confirm that no credentials ended up in the file and that all site-specific values are parameters.
7. Compare the endpoint count against the migration report of the AI assistant.

## Installing the Service

1. Install the service commissioning file. See [Installing Services](/2-4-2/data-flows/services/managing/installing.md).
2. Enable the service. See [Enabling Services](/2-4-2/data-flows/services/managing/enabling.md).

**Result:** Connectware connects to the migrated devices directly and the connections reach the **Connected** state.

{% hint style="info" %}
For read-only validation, Connectware and UMH can usually poll the same device at the same time, which allows you to compare live values before you switch consumers over. Check the connection limits of your devices first. Plan the consumer cutover deliberately: UMH consumers read from Kafka, Connectware consumers from MQTT or through the Kafka connector.
{% endhint %}

## Verifying the Data

Open the [Data Explorer](/2-4-2/monitoring/data-explorer.md) and subscribe to the topics of the migrated service:

* Every migrated data point publishes on its topic with plausible values.
* Values match between the UMH topic browser and Connectware for the same data point.
* The payload shape matches what consumers expect, with a `transform` rule where the UMH shape is required.
* Data arrives at the original poll rates.

## Worked Example

The following UMH Core configuration excerpt defines the location hierarchy and one protocol converter that reads two Modbus data points:

{% code title="umh-config.yaml (excerpt)" lineNumbers="true" expandable="true" %}

```yaml
agent:
  location:
    0: acme
    1: cologne
    2: packaging

protocolConverter:
  - name: press1-modbus
    desiredState: active
    protocolConverterServiceConfig:
      location:
        3: press1
      config:
        dataflowcomponent_read:
          benthos:
            input:
              modbus:
                controller: 'tcp://{{ .IP }}:{{ .PORT }}'
                timeBetweenReads: 1s
                slaveIDs: [1]
                unifiedAddresses:
                  - 'temperature.holding.100.INT16'
                  - 'running.coil.5.BOOL'
            pipeline:
              processors:
                - tag_processor:
                    defaults: |
                      msg.meta.location_path = "{{ .location_path }}";
                      msg.meta.data_contract = "_raw";
                      msg.meta.tag_name = msg.meta.modbus_tag_name;
                      return msg;
            output:
              uns: {}
      variables:
        IP: 192.168.1.100
        PORT: '502'
```

{% endcode %}

Applying the translation rules produces the following service commissioning file. The `modbus` input becomes a Modbus connection with the resolved variables as parameters; `temperature.holding.100.INT16` becomes a holding register endpoint with `fc: 3`, `address: 100` (flagged: verify the base convention against live values), and `dataType: int16BE`; `running.coil.5.BOOL` becomes a coil endpoint; and the topics follow the location hierarchy `acme/cologne/packaging/press1` with the `_raw` contract segment dropped:

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

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

```yaml
description: >
  Service commissioning file migrated from the UMH Core protocol
  converter press1-modbus (Example)

metadata:
  name: United Manufacturing Hub Migration Example
  provider: cybus
  homepage: https://www.cybus.io
  version: 1.0.0

parameters:
  # UMH variable IP
  plcHost:
    description: Host of the protocol converter press1-modbus
    type: string
    default: 192.168.1.100

  # UMH variable PORT
  plcPort:
    description: Port of the protocol converter press1-modbus
    type: integer
    default: 502

definitions:
  # agent.location + converter location: acme.cologne.packaging.press1
  MQTT_TOPIC_PREFIX: acme/cologne/packaging/press1

resources:
  # Protocol converter "press1-modbus" (modbus input)
  press1ModbusConnection:
    type: Cybus::Connection
    properties:
      protocol: Modbus
      targetState: connected
      connection:
        host: !ref plcHost
        port: !ref plcPort

  # Address "temperature.holding.100.INT16", timeBetweenReads 1 s
  # Verify the register base convention against live values.
  temperature:
    type: Cybus::Endpoint
    properties:
      protocol: Modbus
      connection: !ref press1ModbusConnection
      subscribe:
        fc: 3
        address: 100
        length: 1
        dataType: int16BE
        interval: 1000

  # Address "running.coil.5.BOOL", timeBetweenReads 1 s
  running:
    type: Cybus::Endpoint
    properties:
      protocol: Modbus
      connection: !ref press1ModbusConnection
      subscribe:
        fc: 1
        address: 5
        length: 1
        dataType: boolean
        interval: 1000

  mapping:
    type: Cybus::Mapping
    properties:
      mappings:
        - subscribe:
            endpoint: !ref temperature
          publish:
            topic: !sub '${MQTT_TOPIC_PREFIX}/temperature'
        - subscribe:
            endpoint: !ref running
          publish:
            topic: !sub '${MQTT_TOPIC_PREFIX}/running'
```

{% endcode %}

For all Modbus connection and endpoint properties, see [Modbus Connection Properties](/2-4-2/connectors/shop-floor-connectors/modbus-tcp/modbusconnection.md) and [Modbus Endpoint Properties](/2-4-2/connectors/shop-floor-connectors/modbus-tcp/modbusendpoint.md).

{% hint style="info" %}
Disclaimer: United Manufacturing Hub (UMH) and UMH Core are products of UMH Systems GmbH, open source under the Apache License 2.0. Cybus is not affiliated with UMH Systems GmbH.
{% endhint %}


---

# 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/migration/migrating-from-united-manufacturing-hub.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.
