> 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/machine-connectivity/gateways-generic-protocols/connecting-legacy-devices-via-kepware-kepserverex.md).

# Connecting Legacy Devices via Kepware KEPServerEX

This guide shows you how to read data from legacy devices through Kepware KEPServerEX with the Connectware [OPC UA connector](/2-4-2/connectors/shop-floor-connectors/opc-ua/opc-ua-client.md) and map it into an ISA-95 style MQTT topic hierarchy. KEPServerEX is a connectivity platform by PTC with more than 150 device drivers, from current PLC families down to aging serial devices, and it exposes every connected device through a built-in OPC UA server interface. Connectware connects to this interface once and reaches every device that KEPServerEX talks to, which makes the pattern in this guide the standard way to integrate the long tail of legacy equipment that no native connector covers. In more detail, the following topics are covered:

* Understanding how KEPServerEX exposes channels, devices, and tags as OPC UA nodes
* Checking the OPC UA server endpoint in the OPC UA Configuration Manager
* Configuring user authentication and trusting the Connectware client certificate
* Creating the [service commissioning file](/2-4-2/data-flows/service-commissioning-files.md)
* Mapping the data into an ISA-95 style MQTT topic hierarchy
* Verifying data in the [Data Explorer](/2-4-2/monitoring/data-explorer.md)

This guide focuses on the KEPServerEX specifics. For the general workflow of browsing an OPC UA address space and picking NodeIds, see [Using Connectware as an OPC UA Client](/2-4-2/guides/system-connectivity/industry-standards-interoperability/using-connectware-as-an-opc-ua-client.md).

{% hint style="info" %}
Connectware ships native connectors for many shop floor protocols, for example [Modbus/TCP](/2-4-2/connectors/shop-floor-connectors/modbus-tcp.md), [Siemens S7](/2-4-2/connectors/shop-floor-connectors/siemens-simatic-s7.md), [EtherNet/IP](/2-4-2/connectors/shop-floor-connectors/ethernet-ip.md), and [FOCAS](/2-4-2/connectors/shop-floor-connectors/focas.md). If a native connector covers your device, connect it directly and skip the extra hop through KEPServerEX. KEPServerEX is a separately licensed commercial product, so this guide is the right choice when only a KEPServerEX driver covers your device. For an overview of the native connectors, see [Shop Floor Connectors](/2-4-2/connectors/shop-floor-connectors.md).
{% endhint %}

A complete example 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.
* A Windows machine running KEPServerEX 6 that is reachable over the network from Connectware. The steps also apply to ThingWorx Kepware Server, which shares the same platform and configuration tools.
* A KEPServerEX license for the device drivers you use. Without a license, the runtime operates in a time-limited demo mode. For details, see the [KEPServerEX product page](https://www.kepware.com/en-us/products/kepserverex/).
* A channel, a device, and tags already configured in KEPServerEX for the machine you want to read. This guide uses a stamping press connected through a legacy serial driver as an example, but the OPC UA side is identical for every driver.
* Administrator privileges on the Windows machine, because the OPC UA Configuration Manager requires them for certificate handling.
* The username and password of a KEPServerEX user, because anonymous OPC UA sessions are disabled by default.
* 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), [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 KEPServerEX Exposes Tags via OPC UA

A KEPServerEX project is organized in channels, devices, and tags. A channel represents one driver and its physical interface, a device represents one machine on that channel, and tags address the data points of the device. The OPC UA server interface of KEPServerEX mirrors this hierarchy in its address space: each tag becomes an OPC UA Variable node whose string identifier is the full tag path in the project.

{% code lineNumbers="true" %}

```
ns=${NAMESPACE_INDEX};s=${CHANNEL}.${DEVICE}.${TAG}
```

{% endcode %}

* `${NAMESPACE_INDEX}` is the index of the KEPServerEX project namespace. In a default configuration this is `2`, but namespace indexes are not fixed by the OPC UA specification. Verify the index with an OPC UA browser as described in [Using Connectware as an OPC UA Client](/2-4-2/guides/system-connectivity/industry-standards-interoperability/using-connectware-as-an-opc-ua-client.md).
* `${CHANNEL}` and `${DEVICE}` are the channel and device names from your KEPServerEX project.
* `${TAG}` is the tag name. Tag groups add another dot-separated segment, for example `Stamping.Press01.Hydraulics.OilTemperature`.

The OPC UA server listens on port 49320 by default, so the endpoint URL of the server is `opc.tcp://${KEPWARE_HOST}:49320`, where `${KEPWARE_HOST}` is the hostname or IP address of the Windows machine. For the complete list of ports, see [Service Port Assignments](https://support.ptc.com/help/kepware/kepware_server/en/kepware/server/port-assignments.html) in the Kepware documentation.

## Preparing KEPServerEX

The OPC UA server interface is administered with the OPC UA Configuration Manager. To open it, right-click the KEPServerEX Administration icon in the Windows system tray and select **OPC UA Configuration**.

### Checking the OPC UA Server Endpoint

The KEPServerEX installation creates an initial OPC UA endpoint for local connections. Because Connectware connects from another host, check the endpoint definition on the **Server Endpoints** tab:

1. Select the endpoint and click **Edit**.
2. Set **Network Adapter** to an adapter that is reachable from Connectware. An endpoint bound to **Local host only** rejects remote connections.
3. Keep the port number, or note it if your installation uses a custom port. The default is 49320.
4. Check that the security policy `Basic256Sha256` is enabled with the message security mode **Sign and Encrypt**. This is the default and is used in this guide. The `Basic256` and `Basic128Rsa15` policies are deprecated by the OPC Foundation, and the policy `None` disables encryption entirely.
5. Click **OK** and verify that the endpoint is enabled in the list.
6. Apply the changes by right-clicking the Administration icon and selecting **Reinitialize**. Endpoint changes only take effect after the server runtime is reinitialized.

If the Windows firewall is active, add an inbound rule that allows TCP traffic on the endpoint port.

### Configuring User Authentication

By default, KEPServerEX rejects anonymous OPC UA sessions: the **Allow anonymous login** property in the **OPC UA** group of the project properties is set to **No**. Keep this default and give Connectware its own credentials:

1. Right-click the Administration icon and open the **Settings**.
2. In the **User Manager**, add a user for Connectware and assign it to a user group that has read access to the project, and write access if you plan to write tags.
3. Note the username and password. You need them in the service commissioning file.

{% hint style="danger" %}
Setting **Allow anonymous login** to **Yes** gives any OPC UA client on the network access to every connected device. Keep anonymous login disabled in production environments.
{% endhint %}

### Trusting the Connectware Client Certificate

KEPServerEX only accepts OPC UA clients whose certificate it trusts. The first connection attempt from Connectware is rejected, and the Connectware client certificate appears on the **Trusted Clients** tab of the OPC UA Configuration Manager, marked with a red X:

1. Install and enable the service commissioning file of this guide, so that Connectware attempts to connect.
2. In the OPC UA Configuration Manager, open the **Trusted Clients** tab.
3. Select the rejected Connectware certificate and click **Trust**.

Connectware retries the connection automatically and the connection reaches the **Connected** state without further action.

## Choosing the Tags

This guide reads a small set of tags that is typical for machine monitoring on a stamping press. The NodeIds are project-specific: replace the namespace index and the `${CHANNEL}.${DEVICE}.${TAG}` paths with the values from your own KEPServerEX project.

| Tag              | Data type | NodeId (project-specific)                | Sampling interval |
| ---------------- | --------- | ---------------------------------------- | ----------------: |
| `StrokeCounter`  | DWord     | `ns=2;s=Stamping.Press01.StrokeCounter`  |           1000 ms |
| `MachineRunning` | Boolean   | `ns=2;s=Stamping.Press01.MachineRunning` |           1000 ms |
| `OilTemperature` | Float     | `ns=2;s=Stamping.Press01.OilTemperature` |           2000 ms |

OPC UA subscriptions are change-driven: the server samples each tag at the `samplingInterval` and only sends a notification when the value changes. Connectware combines all endpoints with the same `publishInterval` into one OPC UA subscription. For details, see [Connectware Subscriptions](/2-4-2/connectors/shop-floor-connectors/opc-ua/opc-ua-client.md#connectware-subscriptions) and the [OPC UA endpoint properties](/2-4-2/connectors/shop-floor-connectors/opc-ua/opc-ua-client/opcuaendpoint.md).

## Writing the Service Commissioning File

The service commissioning file contains all connection and mapping details. Do not worry about copying the snippets together into one file, the complete example file is available at the end of this guide.

### Description and Metadata

These sections contain general information about the service commissioning file. Only the metadata name is required.

{% code lineNumbers="true" %}

```yaml
description: >
  Service commissioning file that reads tags from legacy devices through the
  OPC UA server interface of Kepware KEPServerEX with the OPC UA connector
  and maps them into an ISA-95 style MQTT topic hierarchy (Example)

metadata:
  name: Kepware KEPServerEX Example
  provider: cybus
  homepage: https://www.cybus.io
  version: 1.0.0
```

{% endcode %}

### Parameters and Definitions

We define the network address and the credentials of the KEPServerEX machine as parameters, so you can set them when you install the service. The default KEPServerEX OPC UA port is 49320.

The MQTT topics in this guide follow an ISA-95 style equipment hierarchy (`<enterprise>/<site>/<area>/<line>/<work-cell>`). We define the prefix once in the `definitions` section and reuse it in every mapping with `!sub`.

{% code lineNumbers="true" %}

```yaml
parameters:
  kepwareHost:
    description: Hostname or IP address of the KEPServerEX machine
    type: string
    default: 192.168.1.100

  kepwarePort:
    description: Port of the KEPServerEX OPC UA server endpoint
    type: integer
    default: 49320

  kepwareUsername:
    description: Username of a KEPServerEX user with access to the project
    type: string
    default: ''

  kepwarePassword:
    description: Password of the KEPServerEX user
    type: string
    default: ''

definitions:
  MQTT_TOPIC_PREFIX: enterprise/hamburg/stamping/line-3/press-01
```

{% endcode %}

### Cybus::Connection

The connection resource establishes the OPC UA session with the KEPServerEX server. The security options match the default endpoint of the server: security policy `Basic256Sha256` with message security mode `SignAndEncrypt`, and username and password authentication because anonymous login is disabled by default. For all connection properties, including custom client certificates and the `connectionStrategy` retry behavior, see [OPC UA Connection Properties](/2-4-2/connectors/shop-floor-connectors/opc-ua/opc-ua-client/opcuaconnection.md).

{% code lineNumbers="true" %}

```yaml
resources:
  kepwareConnection:
    type: Cybus::Connection
    properties:
      protocol: Opcua
      targetState: connected
      connection:
        host: !ref kepwareHost
        port: !ref kepwarePort
        username: !ref kepwareUsername
        password: !ref kepwarePassword
        options:
          securityPolicy: Basic256Sha256
          messageSecurityMode: SignAndEncrypt
```

{% endcode %}

{% hint style="warning" %}
The first connection attempt fails until the Connectware client certificate is trusted on the KEPServerEX machine. Trust the certificate on the **Trusted Clients** tab of the OPC UA Configuration Manager, as described in [Trusting the Connectware Client Certificate](#trusting-the-connectware-client-certificate).
{% endhint %}

### Cybus::Endpoint

Each endpoint subscribes to one tag by its NodeId, according to the table in [Choosing the Tags](#choosing-the-tags). Remember that the NodeIds are project-specific.

{% code lineNumbers="true" %}

```yaml
strokeCounter:
  type: Cybus::Endpoint
  properties:
    protocol: Opcua
    connection: !ref kepwareConnection
    subscribe:
      nodeId: ns=2;s=Stamping.Press01.StrokeCounter
      samplingInterval: 1000
      publishInterval: 1000

machineRunning:
  type: Cybus::Endpoint
  properties:
    protocol: Opcua
    connection: !ref kepwareConnection
    subscribe:
      nodeId: ns=2;s=Stamping.Press01.MachineRunning
      samplingInterval: 1000
      publishInterval: 1000

oilTemperature:
  type: Cybus::Endpoint
  properties:
    protocol: Opcua
    connection: !ref kepwareConnection
    subscribe:
      nodeId: ns=2;s=Stamping.Press01.OilTemperature
      samplingInterval: 2000
      publishInterval: 2000
```

{% endcode %}

### Cybus::Mapping

The mapping publishes each endpoint on a topic of the ISA-95 hierarchy.

{% code lineNumbers="true" %}

```yaml
mapping:
  type: Cybus::Mapping
  properties:
    mappings:
      - subscribe:
          endpoint: !ref strokeCounter
        publish:
          topic: !sub '${MQTT_TOPIC_PREFIX}/stroke-counter'
      - subscribe:
          endpoint: !ref machineRunning
        publish:
          topic: !sub '${MQTT_TOPIC_PREFIX}/machine/running'
      - subscribe:
          endpoint: !ref oilTemperature
        publish:
          topic: !sub '${MQTT_TOPIC_PREFIX}/oil-temperature'
```

{% endcode %}

With this mapping, the stroke counter is published on the topic `enterprise/hamburg/stamping/line-3/press-01/stroke-counter`, and every other tag follows the same pattern.

## Installing the Service Commissioning File

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:** The service is enabled. Connectware opens an OPC UA session with the KEPServerEX server and subscribes to the configured tags. If this is the first connection, trust the Connectware client certificate as described in [Trusting the Connectware Client Certificate](#trusting-the-connectware-client-certificate).

## Verifying the Data

Open the [Data Explorer](/2-4-2/monitoring/data-explorer.md) and subscribe to `enterprise/hamburg/stamping/line-3/press-01/#`. Each topic carries a JSON object with the keys `timestamp` and `value`. For example, the stroke counter:

{% code lineNumbers="true" %}

```json
{
  "timestamp": 1784194200354,
  "value": 4711
}
```

{% endcode %}

Because OPC UA subscriptions are change-driven, a tag that never changes only publishes once after the subscription is established. The quality of the underlying driver connection matters as well: if KEPServerEX loses the connection to the device, the tag quality becomes bad and Connectware receives no further value updates.

If the connection does not reach the **Connected** state, work through the following checks:

* Verify that the KEPServerEX machine is reachable from Connectware on the endpoint port, 49320 by default, and that the Windows firewall allows inbound TCP traffic on it.
* Verify that the endpoint is enabled, bound to a network adapter that is reachable from Connectware, and that the server runtime was reinitialized after endpoint changes.
* Verify that the `securityPolicy` and `messageSecurityMode` of the connection match a security policy that is enabled on the endpoint.
* Verify that the Connectware client certificate is trusted on the **Trusted Clients** tab and not marked with a red X.
* Verify the username and password. The credentials belong to a user in the KEPServerEX User Manager, because anonymous login is disabled by default.

If the connection is established but an endpoint stays in a failed state with a `BadNodeIdUnknown` error, the NodeId does not exist on the server. Check the channel, device, tag group, and tag names against your KEPServerEX project, and verify the namespace index with an OPC UA browser as described in [Using Connectware as an OPC UA Client](/2-4-2/guides/system-connectivity/industry-standards-interoperability/using-connectware-as-an-opc-ua-client.md).

## Service Commissioning File Example

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

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

```yaml
---
# ----------------------------------------------------------------------------
# Service Commissioning File
# ----------------------------------------------------------------------------
# Copyright: Cybus GmbH
# Contact: support@cybus.io
# ----------------------------------------------------------------------------
# Connecting Legacy Devices via Kepware KEPServerEX (Example)
# ----------------------------------------------------------------------------

description: >
  Service commissioning file that reads tags from legacy devices through the
  OPC UA server interface of Kepware KEPServerEX with the OPC UA connector
  and maps them into an ISA-95 style MQTT topic hierarchy (Example)

metadata:
  name: Kepware KEPServerEX Example
  provider: cybus
  homepage: https://www.cybus.io
  version: 1.0.0

parameters:
  kepwareHost:
    description: Hostname or IP address of the KEPServerEX machine
    type: string
    default: 192.168.1.100

  kepwarePort:
    description: Port of the KEPServerEX OPC UA server endpoint
    type: integer
    default: 49320

  kepwareUsername:
    description: Username of a KEPServerEX user with access to the project
    type: string
    default: ''

  kepwarePassword:
    description: Password of the KEPServerEX user
    type: string
    default: ''

definitions:
  # ISA-95 style topic prefix: <enterprise>/<site>/<area>/<line>/<work-cell>
  MQTT_TOPIC_PREFIX: enterprise/hamburg/stamping/line-3/press-01

resources:
  # Connection to the OPC UA server interface of KEPServerEX.
  # The security options match the default endpoint of the server, and
  # username and password are required because anonymous login is
  # disabled by default.
  kepwareConnection:
    type: Cybus::Connection
    properties:
      protocol: Opcua
      targetState: connected
      connection:
        host: !ref kepwareHost
        port: !ref kepwarePort
        username: !ref kepwareUsername
        password: !ref kepwarePassword
        options:
          securityPolicy: Basic256Sha256
          messageSecurityMode: SignAndEncrypt

  # The NodeIds below are project-specific. Replace the namespace index and
  # the <channel>.<device>.<tag> paths with the values from your own
  # KEPServerEX project and verify them with an OPC UA browser.

  # Stroke counter of the press (DWord)
  strokeCounter:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref kepwareConnection
      subscribe:
        nodeId: ns=2;s=Stamping.Press01.StrokeCounter
        samplingInterval: 1000
        publishInterval: 1000

  # Machine running flag (Boolean)
  machineRunning:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref kepwareConnection
      subscribe:
        nodeId: ns=2;s=Stamping.Press01.MachineRunning
        samplingInterval: 1000
        publishInterval: 1000

  # Hydraulic oil temperature (Float)
  oilTemperature:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref kepwareConnection
      subscribe:
        nodeId: ns=2;s=Stamping.Press01.OilTemperature
        samplingInterval: 2000
        publishInterval: 2000

  mapping:
    type: Cybus::Mapping
    properties:
      mappings:
        - subscribe:
            endpoint: !ref strokeCounter
          publish:
            topic: !sub '${MQTT_TOPIC_PREFIX}/stroke-counter'
        - subscribe:
            endpoint: !ref machineRunning
          publish:
            topic: !sub '${MQTT_TOPIC_PREFIX}/machine/running'
        - subscribe:
            endpoint: !ref oilTemperature
          publish:
            topic: !sub '${MQTT_TOPIC_PREFIX}/oil-temperature'
```

{% endcode %}

{% hint style="info" %}
Disclaimer: Kepware, KEPServerEX, and ThingWorx are trademarks or registered trademarks of PTC Inc. or its subsidiaries in the United States and other countries.
{% 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/machine-connectivity/gateways-generic-protocols/connecting-legacy-devices-via-kepware-kepserverex.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.
