> 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/guides/system-connectivity/mes-erp-business-systems/sap-digital-manufacturing-integration.md).

# SAP Digital Manufacturing Integration

This guide describes how to integrate SAP Digital Manufacturing (SAP DM) with Connectware. You configure a service commissioning file that sends shop floor data to SAP DM through its public REST APIs and receives data from SAP DM production processes in return. A complete example file is available at the end of this guide.

## Objectives

* Establishing an OAuth-authenticated connection between Connectware and the SAP DM public API.
* Starting a SAP DM production process with shop floor data.
* Logging data collection values against a shop floor control (SFC) number.
* Receiving data from SAP DM production processes in Connectware.

## Prerequisites

To follow this guide, you will need the following:

* A running instance of Cybus Connectware.
* Access to a SAP DM tenant, including a service key of the SAP DM service instance on SAP Business Technology Platform (BTP). The service key contains the public API endpoint, the OAuth token URL, the client ID, and the client secret.
* A production process created in the SAP DM Production Process Designer, and its process definition key.
* For data collection: a plant, an SFC number, and a data collection group in SAP DM master data.
* Access to the [Admin UI](/access/admin-ui.md) with sufficient [user permissions](/access/user-management.md).
* Basic knowledge of MQTT and the Connectware [services](/data-flows/services.md) concept (for example, [service commissioning files](/data-flows/service-commissioning-files.md), [connections](/data-flows/service-commissioning-files/resources/cybus-connection.md), and [endpoints](/data-flows/service-commissioning-files/resources/cybus-endpoint.md)).

## Connectware and SAP DM Integration

SAP DM exposes its functionality as REST APIs on a public API endpoint of the form `api.<region>.dmc.cloud.sap`, authenticated with OAuth 2.0 client credentials. Connectware communicates with these APIs through the [HTTP/REST connector](/connectors/enterprise-connectors/http-rest.md), which handles token retrieval and renewal automatically.

This guide uses the two most common APIs for sending shop floor data to SAP DM:

* **Production Process API**: Starts one execution of a production process per message. The message body becomes the process input. Inside the production process, you decide what happens with the data. This is the most flexible entry point.
* **Data Collection API**: Logs measured values, such as torque or temperature, directly against an SFC number in a data collection group. No production process is required.

For the opposite direction, Connectware hosts an HTTP route using the [HTTP Server](/connectors/servers/http-server.md) resource. A SAP DM production process calls this route to send data back to the shop floor.

The MQTT topics in this guide follow an ISA-95-style equipment hierarchy (`<enterprise>/<site>/<area>/<line>/<cell>`). The mappings subscribe with wildcards across all levels, so any machine in the hierarchy is picked up without changing the integration.

### SAP DM Connection Properties

The connection to SAP DM requires values from the service key of your SAP DM service instance. We add them as parameters to the service commissioning file, so you can set them when you install the service.

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.

* `sapDmApiHost`: The public API endpoint of your SAP DM tenant, without the scheme. For example, `api.eu20.dmc.cloud.sap`.
* `oauthTokenUrl`: The OAuth token endpoint. For example, `https://<tenant>.authentication.<region>.hana.ondemand.com/oauth/token`.
* `oauthClientId` and `oauthClientSecret`: The OAuth client credentials.
* `processDefinitionKey`: The key of the production process to start, shown in the Production Process Designer. For example, `REG_00000000-0000-0000-0000-000000000000`.
* `topicRoot`: The root of the MQTT topic hierarchy. Defaults to `enterprise`.

{% code lineNumbers="true" %}

```yaml
parameters:
  sapDmApiHost:
    description: Public API host of your SAP DM tenant
    type: string
    default: api.eu20.dmc.cloud.sap

  oauthTokenUrl:
    description: OAuth token endpoint from the service key of your SAP DM instance
    type: string
    default: https://example.authentication.eu20.hana.ondemand.com/oauth/token

  oauthClientId:
    description: OAuth client ID from the service key
    type: string

  oauthClientSecret:
    description: OAuth client secret from the service key
    type: string

  processDefinitionKey:
    description: Key of the SAP DM production process to start
    type: string
    default: REG_00000000-0000-0000-0000-000000000000

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

{% endcode %}

### SAP DM Connection

To connect to the SAP DM public API, we set up a `Cybus::Connection` resource that uses the HTTP/REST connector with the [OAuth 2.0 Client Credentials Grant](https://docs.cybus.io/guides/system-connectivity/mes-erp-business-systems/pages/Hij6TsDxB4GxfyynBwLn#oauth-2.0-client-credentials-grant). Connectware fetches the bearer token from the token endpoint and refreshes it before it expires. The endpoints that use this connection do not need any authentication configuration of their own.

{% code lineNumbers="true" %}

```yaml
resources:
  sapDmConnection:
    type: Cybus::Connection
    properties:
      protocol: Http
      connection:
        scheme: https
        host: !ref sapDmApiHost
        port: 443
        oauthClientCredentials:
          auth_url: !ref oauthTokenUrl
          client_id: !ref oauthClientId
          client_secret: !ref oauthClientSecret
```

{% endcode %}

### Starting a Production Process

The Production Process API starts one execution of a production process per POST request. The process definition key identifies the process, and the request body becomes the process input.

We define a write endpoint for the API path and a mapping that feeds it from the MQTT topic hierarchy. The HTTP/REST connector expects the request body in the `body` property of the message (see [Publishing Data to REST Servers](/connectors/enterprise-connectors/http-rest.md#publishing-data-to-rest-servers)). The `transform` rule wraps the incoming payload accordingly, so machines can publish their data without knowing about this convention.

{% code lineNumbers="true" %}

```yaml
processStartEndpoint:
  type: Cybus::Endpoint
  properties:
    protocol: Http
    connection: !ref sapDmConnection
    write:
      path: !sub '/pe/api/v1/process/processDefinitions/start?key=${processDefinitionKey}'

processStartMapping:
  type: Cybus::Mapping
  properties:
    mappings:
      - subscribe:
          topic: !sub '${topicRoot}/+site/+area/+line/+cell/process-data'
        publish:
          endpoint: !ref processStartEndpoint
        rules:
          - transform:
              expression: '{ "body": $ }'
```

{% endcode %}

Any message published to a matching topic, for example `enterprise/hamburg/assembly/line-1/press-01/process-data`, now starts one execution of the production process. The payload structure is up to you, it must match the input parameters that you defined for the process in the Production Process Designer:

{% code lineNumbers="true" %}

```json
{
  "plant": "PLANT1",
  "resource": "PRESS-01",
  "temperature": 42.1,
  "serial": "SN-0001"
}
```

{% endcode %}

### Logging Data Collection Values

The Data Collection API writes measured values directly against an SFC number, without a production process in between. The endpoint uses the same connection and the `/datacollection/v1/log` path of the Log DC Values service.

{% code lineNumbers="true" %}

```yaml
dataCollectionLogEndpoint:
  type: Cybus::Endpoint
  properties:
    protocol: Http
    connection: !ref sapDmConnection
    write:
      path: /datacollection/v1/log

dataCollectionLogMapping:
  type: Cybus::Mapping
  properties:
    mappings:
      - subscribe:
          topic: !sub '${topicRoot}/+site/+area/+line/+cell/dc-values'
        publish:
          endpoint: !ref dataCollectionLogEndpoint
        rules:
          - transform:
              expression: '{ "body": $ }'
```

{% endcode %}

The message payload must follow the request schema of the Data Collection API. The plant, the SFC number, and the data collection group must exist in your SAP DM master data. For the complete schema, refer to the Data Collection API in the [SAP Business Accelerator Hub](https://api.sap.com/package/SAPDigitalManufacturingCloud/rest).

{% code lineNumbers="true" %}

```json
{
  "plant": "PLANT1",
  "sfc": "SFC-0001",
  "group": { "dcGroup": "TEMPERATURE_CHECK", "version": "A" },
  "parameterValues": [{ "name": "TEMPERATURE", "value": "42.1" }]
}
```

{% endcode %}

### Receiving Data from SAP DM

For the return direction, Connectware hosts an HTTP route using the `Cybus::Server::Http` and `Cybus::Node::Http` resources. A mapping publishes every request body that arrives on this route to an MQTT topic, where any other Connectware service can pick it up, for example to write an acknowledgment back to a PLC.

{% code lineNumbers="true" %}

```yaml
sapDmResponseServer:
  type: Cybus::Server::Http
  properties:
    basePath: /sap-dm

sapDmResponseRoute:
  type: Cybus::Node::Http
  properties:
    parent: !ref sapDmResponseServer
    method: POST
    route: /response

responseMapping:
  type: Cybus::Mapping
  properties:
    mappings:
      - subscribe:
          endpoint: !ref sapDmResponseRoute
        publish:
          topic: !sub '${topicRoot}/sap-dm/response'
```

{% endcode %}

The route is served under the `/data` prefix of your Connectware instance: `https://<connectware>/data/sap-dm/response`. In your production process, add a step that sends an HTTP POST request to this URL with the `Content-Type: application/json` header.

The calling user must be authenticated and needs write permission on the path `data/sap-dm/response`. For more information, see [HTTP Server Permissions](/connectors/servers/http-server.md#permissions).

## Verifying the Integration

1. Install the service and set the parameters with the values from your service key.
2. Check that the connection is in the **Connected** state on the service details page in the Admin UI. If the OAuth credentials are wrong, the connection does not reach the connected state.
3. Publish a test message to `enterprise/hamburg/assembly/line-1/press-01/process-data`, for example with an MQTT client or the Admin UI.
4. Open the production process monitoring in SAP DM and check that a new process instance has been started. For data collection, open the Work Center POD, select the SFC and operation, and check the data collection panel.
5. The result of every HTTP request is published to the `/res` topic of the endpoint. Use the [Data Explorer](/monitoring/data-explorer.md) to inspect it. If SAP DM rejects a request, the message on the `/res` topic contains an `error` property with the HTTP status.

## Service Commissioning File Example

{% file src="/files/0fY9EYmKmF8PizSdA3s3" %}

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

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

description: >
  Service commissioning file for the bidirectional integration between
  Connectware and SAP Digital Manufacturing (Example)

metadata:
  name: SAP Digital Manufacturing Integration
  provider: cybus
  homepage: https://www.cybus.io
  version: 1.0.0

parameters:
  sapDmApiHost:
    description: Public API host of your SAP DM tenant
    type: string
    default: api.eu20.dmc.cloud.sap

  oauthTokenUrl:
    description: OAuth token endpoint from the service key of your SAP DM instance
    type: string
    default: https://example.authentication.eu20.hana.ondemand.com/oauth/token

  oauthClientId:
    description: OAuth client ID from the service key
    type: string

  oauthClientSecret:
    description: OAuth client secret from the service key
    type: string

  processDefinitionKey:
    description: Key of the SAP DM production process to start
    type: string
    default: REG_00000000-0000-0000-0000-000000000000

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

resources:
  # Connection to the SAP DM public API using OAuth 2.0 client credentials
  sapDmConnection:
    type: Cybus::Connection
    properties:
      protocol: Http
      connection:
        scheme: https
        host: !ref sapDmApiHost
        port: 443
        oauthClientCredentials:
          auth_url: !ref oauthTokenUrl
          client_id: !ref oauthClientId
          client_secret: !ref oauthClientSecret

  # Starts one execution of a SAP DM production process per message
  processStartEndpoint:
    type: Cybus::Endpoint
    properties:
      protocol: Http
      connection: !ref sapDmConnection
      write:
        path: !sub '/pe/api/v1/process/processDefinitions/start?key=${processDefinitionKey}'

  processStartMapping:
    type: Cybus::Mapping
    properties:
      mappings:
        - subscribe:
            topic: !sub '${topicRoot}/+site/+area/+line/+cell/process-data'
          publish:
            endpoint: !ref processStartEndpoint
          rules:
            - transform:
                expression: '{ "body": $ }'

  # Logs data collection values against an SFC
  dataCollectionLogEndpoint:
    type: Cybus::Endpoint
    properties:
      protocol: Http
      connection: !ref sapDmConnection
      write:
        path: /datacollection/v1/log

  dataCollectionLogMapping:
    type: Cybus::Mapping
    properties:
      mappings:
        - subscribe:
            topic: !sub '${topicRoot}/+site/+area/+line/+cell/dc-values'
          publish:
            endpoint: !ref dataCollectionLogEndpoint
          rules:
            - transform:
                expression: '{ "body": $ }'

  # HTTP route that SAP DM production processes can call back
  sapDmResponseServer:
    type: Cybus::Server::Http
    properties:
      basePath: /sap-dm

  sapDmResponseRoute:
    type: Cybus::Node::Http
    properties:
      parent: !ref sapDmResponseServer
      method: POST
      route: /response

  responseMapping:
    type: Cybus::Mapping
    properties:
      mappings:
        - subscribe:
            endpoint: !ref sapDmResponseRoute
          publish:
            topic: !sub '${topicRoot}/sap-dm/response'
```

{% 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/guides/system-connectivity/mes-erp-business-systems/sap-digital-manufacturing-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.
