Skip to Content
Author's profile photo Lukas Riegel

Connecting SAP Plant Connectivity to SAP Cloud Platform Internet of Things for the Cloud Foundry Environment (and SAP IoT Application Enablement)

Introduction

Since version 15.1 SP5 MQTT source and destination systems are available in SAP Plant Connectivity (PCo). In the 15.2 release of PCo, client certificates have been added to the authentication for the Universal Web service destination system.
This provides the required capabilities in order to connect PCo technically to SAP Cloud Platform Internet of Things for the Cloud Foundry Environment (also known as IoT Services).
In this blog post, we will illustrate how to configure the end to end connection of those systems.

Prerequisites

  • An installation of SAP Plant Connectivity
  • A tenant for SAP Cloud Platform Internet of Things for the Cloud Foundry Environment
  • A tenant for SAP IoT Application Enablement
  • Both tenants must be connected if you want to see your data in SAP IoT Application Enablement

Scenario

We are going to stick to the exemplary data model provided in the Starter Kit for the SAP Cloud Platform Internet of Things. This model consist of an “Ambient” capability able to measure Humidity, Temperature and Light.
The goal is to send some measurements from SAP Plant Connectivity to the modelled instance.

Package configuration

First step is to set up the data model in SAP IoT Application Enablement. The example will be based on the APIs of SAP IoT Application Enablement:
POST /Configuration
{
  "version": "1.0.0",
  "id": "<packageId>",
  "scope": "private",
  "description": {
    "en": ""
  },
  "dependencies": [],
  "services": {
    "dataService": {
      "thingTypes": [
        {
          "name": "<packageId>:iotstarterkit",
          "description": {
            "en": ""
          },
          "propertyTypes": [
            {
              "id": "Ambient",
              "description": {
                "en": ""
              },
              "propertySetType": "<packageId>:Ambient"
            },
            {
              "id": "Image",
              "propertySetType": "<packageId>:Image"
            }
          ]
        }
      ],
      "propertySetTypes": [
        {
          "name": "<packageId>:Default",
          "description": {
            "en": "Default PST"
          },
          "dataCategory": "MasterData",
          "propertyTypes": []
        },
        {
          "name": "<packageId>:Image",
          "description": {
            "en": "Image properties"
          },
          "dataCategory": "MasterData",
          "propertyTypes": [
            {
              "value": {
                "description": {},
                "id": "ImageName",
                "length": "127",
                "type": "String"
              }
            }
          ]
        },
        {
          "name": "<packageId>:Ambient",
          "description": {
            "en": ""
          },
          "dataCategory": "TimeSeriesData",
          "propertyTypes": [
            {
              "value": {
                "description": {},
                "id": "Humidity",
                "type": "Numeric",
                "unitOfMeasure": "%",
                "qualityCode": "0"
              }
            },
            {
              "value": {
                "description": {},
                "id": "Temperature",
                "type": "NumericFlexible",
                "unitOfMeasure": "°C",
                "qualityCode": "0"
              }
            },
            {
              "value": {
                "description": {},
                "id": "Light",
                "type": "Numeric",
                "unitOfMeasure": "CD",
                "qualityCode": "0"
              }
            }
          ],
          "annotations": []
        }
      ]
    }
  }
}
Please note down the id of the capability.
Now, we are going to bring the capability together in one SensorType:
POST /iot/core/api/v1/sensorTypes

{
  "name": "iotstarterkit",
  "capabilities": [
    {
      "id": "<capability id measure>",
      "type": "measure"
    }
  ]
}
Please note down the id of your sensor type.
Finally, we can create our device and attach a sensor to this device:
POST /iot/core/api/v1/devices

{
  "name": "IoTStarterkit-Device",
  "gatewayId": "<mqtt gateway id>"
}
POST /iot/core/api/v1/sensors

{
  "name": "IoTStarterkit-Sensor",
  "deviceId": "<your device id>",
  "sensorTypeId": "<your sensor type id>"
}
Once again, please note down the id and the alternate id of your device and your sensor.

Thing onboarding

Now, we will create a Thing in Application Enablement. We are going to model a robot with one arm. At the end of this blog post, we are going to send commands to this robot arm via MQTT.
POST /Things

{
  "_externalId": "IoTStarterkit-Device1",
  "_name": "IoTStarterkit-Device1",
  "_description": {
    "en": "IoTStarterkit Thing"
  },
  "_thingType": [
    "<packageId>:iotstarterkit"
  ],
  "_objectGroup": "<your_ObjectGroup>"
}
Here again, please note down the id of the created Thing.
The next step is to connect the Thing in IoT Application Enablement with the Sensor in IoT Services. This is done using the following API call:
POST /mappings/sensorthing

[
  {
    "thingId": "<thingId>",
    "sensorId": "<sensorId>"
  }
]

SAP Plant Connectivity Configuration

In order to speed up the configuration we provide a template for configuring the connectivity from SAP Plant Connectivity to IoT Services.
Please import the template file in PCo. The password is mentioned in the linked webpage.
After importing the template configuration, you should be able to see one Source System and two Destination Systems as shown in the screenshot below:

Required Configuration Steps

  • Source System – Section Client: Client ID
  • Source System – Section Client: Server URI
  • Source System – Section Connection: Session Certificate
  • Destination System – Section Message Settings: Topic Name
The above mentioned steps are required in order to adjust the template to your system.
We will guide you through those steps in the following section of this blog.
The first step is to adjust the Client ID and Server URI in the configuration. To do so, please select the Source System and ensure you are on the tab called ‘Client’ on the righthand side. Use the alternateId of your Device as Client ID and point the Server URI to your IoT Services tenant.
SAP Cloud Platform Internet of Things for the Cloud Foundry Environment allows devices to connect to the Internet of Things Gateway Cloud (using MQTT or REST) through a secure TLS connection, where client certificate authentication is in place. Thereby, Transport Layer Security, version 1.2 (TLS1.2) is used. To establish a secure connection from SAP Plant Connectivity to the Gateway Cloud it is necessary to configure the so called ‘Session Certificate’ in SAP Plant Connectivity. This is done one the second section in the source system called ‘Connection’. Please select the certificate matching to your device here. The certificate has to be downloaded from IoT Services (either through the Cockpit or using the APIs) and imported into the Windows Certificate Store. A guide how to do this is published by Microsoft on their website – this guide is valid until step 15.
The ClientID has to be configured in the destination system as well. This is done on the last section called ‘Message Settings’. Please use the alternate Id of your device here again.

SAP Plant Connectivity Configuration Test

Normally, data would be consumed/collected from a source system like OPC UA, OPC DA or Modbus in PCo and then sent to the destination system – in out case the destination system we configured in the previous steps. To allow testing of the destination without the need to connect to a actual source system we created a second destination system called ‘SAP_CP_IoT_MQTT_Testing’. This can be used for your local tests. It basically uses some variables, that can be manually entered and calls the MQTT destination system with them.
To start your configuration, please select the ‘SAP_CP_IoT_MQTT_Testing’ destination and select the second section called ‘Variables’. Herein maintain the variables – especially the sensorAlternateId and capabilityAlternateId. Please ensure those values match the alternateId of your previously created Sensor, respectively Capability.
To finally test the MQTT destination, please click on the ‘Test Configuration’ button highlighted in the screenshot.
After executing the local test in PCo you should be able to review the data arrived in SAP Cloud Platform Internet of Things. To do so, please navigate to your tenant and use the ‘Data Visualization’ to review the data sent to the Gateway Cloud MQTT.
As we connected our Thing we modelled in SAP IoT Application Enablement with the sensor in IoT Services we are able to see the data in IoT Application Enablement, too.

Summary

I hope you could follow all the explained steps and got an overview of the required steps to establish a connection between SAP PCo and SAP Cloud Platform Internet of Things for the Cloud Foundry Environment. Feel free to ask your questions in the comments, if there are any open.

Assigned Tags

      26 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Vivek Gupta
      Vivek Gupta

      Hi Lukas Riegel

      Thanks for the nice blog really good .

      As you configure Device alternate-id in source system configuration and wherein in configuration test you have configured sensorAlternateId and capabilityAlternateId – My question is what is difference here.?

      Also you imported the template file in PCo.for fast configuration – So, this file holding what information ?

      Thanks ~

      Vivek Gupta

       

      Author's profile photo Lukas Riegel
      Lukas Riegel
      Blog Post Author

      Hi Vivek,

       

      Please see the documentation of SAP Cloud Platform Internet of Things for the Cloud Foundry Environment for an explanation of the terms.

      The template file provides all required parts that you would normally need to configure in SAP Plant Connectivity: Source Systems, Destination Systems, Agent Instances and Notifications.

       

      Regards,

      Lukas

       

      Author's profile photo Rainer Betrich
      Rainer Betrich

      Hi Lukas,

      cool, that sounds promising, that PCo could talk to IOT CF.

      I think I will give it a try for a comparison with IOT Gateway Edge.

       

      Thanks for that valuable blog.

      Rainer

       

      Author's profile photo Khaleelurrehman Dawoodsaheb Badeghar
      Khaleelurrehman Dawoodsaheb Badeghar

      Hi Lukas,

      Thank you very much. This is very exciting topic useful in lots of use cases in manufacturing space and building Intelligent Enterprise

      If you could elaborate few basic steps in Package configuration that would be helpful.

      Please pardon my ignorance. How does that IoTStarterkit-Device and IoTStarterkit-Device1 appear in IoT cockpit and IoTAE respectively.

      I clicked the link given in Scenario section and it took me to a page and I found "Supported IoT Service versions". I was stuck on what to do next. I clicked IoT CF link and it took me to another page. I wondered how that IoTStarterkit-Device appeared in IoT Cockpit without manually configuring them. I know all the steps of how to on board an individual device, create capabilities, sensor types, sensors and link it to IoT AE Thing.

      Your help is appreciated.

      Thanks and Regards

      Khaleel

      Author's profile photo Lukas Riegel
      Lukas Riegel
      Blog Post Author

      Hi Kahaleel,

      check out the IoT Starterkit. They provide varios scripts to automatically create the required entities in the system.

      Regards,

      Lukas

      Author's profile photo Arush Saxena
      Arush Saxena

      Great blog Lukas. Very helpful ?

      Quick question: How could you batch multiple MQTT payloads and send them together where each payload is for a different capability.

      Here’s an example payload that we want to send through PCo. I wrote a python script that can combine all of these together and send as one MQTT payload. With python, it works fine. I want to replicate that functionality with PCo.

      [{“capabilityAlternateId”: “IG_87800180D08201081600C406F02CBA47”, “sensorAlternateId”: “7da4944d4e0a0128”, “timestamp”: “2018-07-01T04:00:00-04:00”, “measures”: [{“I_bearingTemp_97”: “100.0207672”}]},

       

      {“capabilityAlternateId”: “IG_88800180D08201081600C406F02CBA47”, “sensorAlternateId”: “7da4944d4e0a0128”, “timestamp”: “2018-07-01T04:00:00-04:00”, “measures”: [{“I_bearingTemp_97”: “139.8439484”}]},

       

      {“capabilityAlternateId”: “IG_85800180D08201081600C406F02CBA47”, “sensorAlternateId”: “7da4944d4e0a0128”, “timestamp”: “2018-07-01T04:00:00-04:00”, “measures”: [{“I_rotorSpeed_97”: “1980.329883”, “I_axialDisp_97”: “0.499012925”}]},

       

      {“capabilityAlternateId”: “IG_86800180D08201081600C406F02CBA47”, “sensorAlternateId”: “7da4944d4e0a0128”, “timestamp”: “2018-07-01T04:00:00-04:00”, “measures”: [{“I_windingTemp1_97”: “130.1672516”}]}]

      Imagine there’s an equipment which has 4 components. All the 4 components have the same sensorAlternateId but each component has a unique capabilityAlternateId. I defined the destination in PCo for one payload for a component, for ex.

       

      {“capabilityAlternateId”: “IG_87800180D08201081600C406F02CBA47”, “sensorAlternateId”: “7da4944d4e0a0128”, “timestamp”: “2018-07-01T04:00:00-04:00”, “measures”: [{“I_bearingTemp_97”: “100.0207672”}]}

       

      But, I’m not sure how I could concatenate the payloads for each component to send as one message. I’d appreciate your thoughts.

      Author's profile photo Lukas Riegel
      Lukas Riegel
      Blog Post Author

      Hi Arush,

      good question - I can completely understand your question and the scenario you are talking about makes sense.

      You have to use the syntax $in[i].parameter if you want to create an array without a root element in the MQTT payload.

      This will generate the following payload for your scenario:

      [
        {
          "sensorAlternateId": "7da4944d4e0a0128",
          "capabilityAlternateId": "IG_87800180D08201081600C406F02CBA47",
          "measures": [
            {
              "I_bearingTemp_97": "2"
            }
          ],
          "timestamp": "2018-07-01T04:00:00-04:00"
        },
        {
          "sensorAlternateId": "7da4944d4e0a0128",
          "capabilityAlternateId": "IG_88800180D08201081600C406F02CBA47",
          "measures": [
            {
              "I_bearingTemp_97": "3"
            }
          ],
          "timestamp": "2018-07-01T04:00:00-04:00"
        },
        {
          "sensorAlternateId": "7da4944d4e0a0128",
          "capabilityAlternateId": "IG_85800180D08201081600C406F02CBA47",
          "timestamp": "2018-07-01T04:00:00-04:00",
          "measures": [
            {
              "I_rotorSpeed_97": "4",
              "I_axialDisp_97": "1"
            }
          ]
        },
        {
          "sensorAlternateId": "7da4944d4e0a0128",
          "capabilityAlternateId": "IG_86800180D08201081600C406F02CBA47",
          "timestamp": "2018-07-01T04:00:00-04:00",
          "measures": [
            {
              "I_windingTemp1_97": "5"
            }
          ]
        }
      ]

      Regards,

      Lukas

      Author's profile photo Lukas Riegel
      Lukas Riegel
      Blog Post Author

      Remark: Above example requires at least PCo Version 15.2 SP03

      Author's profile photo Thomas Halliday
      Thomas Halliday

      Hi Lukas, I’m getting an error:

      Fixed and dynamic indexes are defined simultaneously for expression path ‘$in[0].measures’.

      Is there something wrong with my Message Config?

      Author's profile photo Anish Vyas
      Anish Vyas

      Hello Lukas,

       

      Brilliant article. Explains a lot of nitty gritty things.

      One question though, Is there a way to check whether there is any way to listen to the data that we have populated?

      Our use case is that we need to send the received data on PCo to SAP MII (Manufacturing Integration and Intelligence). We are thinking of doing that by creating Agent Instance and then creating a notification to subscribe to the required information.

      Any help would be really appreciated.

       

      Regards

      Anish Vyas

      Author's profile photo Lukas Riegel
      Lukas Riegel
      Blog Post Author

      Hello Mr. Vyas,

      can you please explain the scenario you are talking about a little bit more in detail?

      Regards,

      Lukas

      Author's profile photo Anish Vyas
      Anish Vyas

      Sure.

       

      Here's our scenario :

      We have a total of 3 systems involved in this setup : SAP MII(Manufacturing Integration and Intelligence), SAP PCo and Machine Simulator based on Raspberry Pi. We are using an IOT Tenant (IOT Cockpit 4.0) as the MQTT message broker to establish connectivity between Pco and the Raspberry Pi.

      We have created a Device on SAP IoT 4.0 Cockpit and have been able to establish certificate based authentication between the  device and PCo. We have created a Measure capability on the device and we have been able to send static data from the Pco system onto the IOT 4.0 Device by creating a MQTT Destination system on SAP PCo and calling it using a Multi-Call Destination System in SAP PCo using temporary variables as described by your blog.

      We are able to view this data in the capability of the device on the IOT Cockpit.

      What we need to understand now is, how do we read/receive data from he IOT Device onto the Pco System so that we can forward that to the MII system. This data will be sent from the Simulator to the IOT Device and we need to read in the PCo system.

       

      Below is a diagram depicting the flow which we have :

       

      Let us know if you need more clarification  on this.

      Author's profile photo Andreas Gerstner
      Andreas Gerstner

      Excellent post. Can you tell me if there was a way to use the same scenario on port 443 as well? PCo doesn't offer a port to be specified and so it is using 8883 per default. if I added :443 to the url it doesn't work. My Company doesn't want to open port 8883 at all. any idea on how I could resolve this?

      Andreas

      Author's profile photo Reiner Eberhard
      Reiner Eberhard

      Hello,

       

      I download the template and tried to import in latest version 15.3 but get an error: The password is invalid.

      How can I import the template to PCo 15.3?

      BR

      Reiner

      Author's profile photo Lukas Riegel
      Lukas Riegel
      Blog Post Author

      Hello Reiner,

      can you please try again and confirm that you are typing in the password?

      I'm able to import the template in 15.3 - but only if I type in the password. Copy&Paste shows the same error as reported by your.

       

      Regards,

      Lukas

      Author's profile photo Reiner Eberhard
      Reiner Eberhard

      Hi Lukas,

       

      as you say copy&paste PW is not working, it must be typed in...

       

      BR

      Reiner

      Author's profile photo Supriya Malakar
      Supriya Malakar

      Hi Lukas ,

      Thanks for this great article it's really very helpful .I need your help on creating below kind of structure in MQTT destination system Message Settings Tab . In Parameter I am putting measurements[2] but it doesn't works .

      {"machineId":"a", "measurements": [{"sensorId":"a", "value": 5.0, "timestamp": "2019-07-27T11:13:00.0"}, {"sensorId":"b", "value": 12.0, "timestamp": "2019-07-27T11:13:00.0"}], "timestamp": "2019-07-27T11:13:00.0"}

      How can I use Bundling index to make proper Parameter structure .

      Author's profile photo Lukas Riegel
      Lukas Riegel
      Blog Post Author

      Hello Supriya,

      Given you payload structure, I would assume, that you want to send one message to the mqtt destination system containing two different measurements (sensor 'a' and 'b'). Therefore, the Message Bundling function is most probably not the right choice (usually used for scenarios like: collect 10 sensor readings (different timestamps) and send one message containing all values to reduce network load).

      The given payload structure can be build using measurements[0].sensorId, .... (all fields in the object) followed by a measurements[1].sensorId ....

      Author's profile photo Supriya Malakar
      Supriya Malakar

      Thanks Lukas.

      Author's profile photo Thomas Halliday
      Thomas Halliday

      Hi Lukas,

      Is there any way to check SCP connection is working? I have followed your tutorial closely, however my data is not showing in Data Visualization, and I don't think it's the payload.

      Payload:

      {"capabilityAlternateId":"IG_E41D1730F62EF78F1600E206428F13A8","sensorAlternateId":"3a547e9a-ee43-46ac-a276-794e00da19aa","measures":[{"I_Accel_X":2,"I_Accel_Z":3,"I_Accel_Y":4,"I_Health_Score":5}]}
      Author's profile photo Lukas Riegel
      Lukas Riegel
      Blog Post Author

      Hi Thomas,

       

      Are you using MQTT or REST?

      For MQTT you can use the ack topic: https://help.sap.com/viewer/643f531cbf50462c8cc45139ba2dd051/Cloud/en-US/5e566abffba845ecb651b9d968ebac5f.html

       

      It may also receive notifications about the processing status of the published measures. In order to receive such notifications, the device should subscribe to the ack/<device alternate ID> topic

      Author's profile photo Thomas Halliday
      Thomas Halliday

      My mistake Lucas, I realized my Destination System was targeting the wrong client! I've changed the target and now the system is working.

      Thanks very much for a comprehensive tutorial!

      Author's profile photo Supriya Malakar
      Supriya Malakar

      I am getting an error while configuring device certificate in SAP Pco.I have imported into the Windows Certificate Store and then configuring the same certificate in Pco as a client certificate .I am using Pco 15.3.0.7.


      Author's profile photo Lukas Riegel
      Lukas Riegel
      Blog Post Author

      Can you please remove the input in the the User Name & Password fields visible on your screenshots and retry?

      Author's profile photo Supriya Malakar
      Supriya Malakar

      I tried by removing user Name and Password.still issue is same.Once I configure certificates in Pco then this issue is happening.

      Author's profile photo Guillaume URIEN
      Guillaume URIEN

      Hello Lukas,

      Thank you for this excellent blog.

      I'm currently working on a projet where data will be collected using PCo and then send to SCP IoT services for usage in PdMS.

      PCo is already installed and data will be collected using OPC UA protocol. My idea is then to send this data using MQTT GW of IoT service. Neverthless I do not understand how to link the OPC UA sources with MQTT destination taking into account that I have to create a MQTT client in the source system as well.

      Then my question is how to make this link between an OPC-UA sources and then send it to IoT services?

      Thanks in advance for your help,

      Guillaume