Skip to Content
Technical Articles

SAP Predictive Maintenance and Service (PdMS) – From Sensor Readings to Health Indicators (Part 3) – Uploading Data using the REST API

Introduction

In part two of the blog post series, we have published the Equipment Model and created one Equipment from the Model. Afterwards, we checked and retrieved the mapping of the Objects to the external Systems.

In this part of the blog post, we are going to upload sensor data to Leonardo IoT and verify that it arrives in the SAP Predictive Maintenance and Service (PdMS).

Previous Posts

Pre-Requisites

To upload sensor data to Leonardo IoT (the new name of IoT Application Enablement), we need the authorization to do so. This means, we either need a service key or we need to be able to login into the Leonardo IoT Launchpad. In this blog post, we are using the service key method.

Recap

In the last blog post we created one Equipment (Asset Central Id: 44F6588537524198BF895C376D0B81FF and Thing Id: CF1446EF0F3B481684E3F1E1A391E182) which we created from Model Weather Station (Asset Central Id: D9B4D6A2FDBA4E888A7527220D351150, ThingType: dca.demo.sap.weatherstation:M_Weather_Station).

We have the following mappings for Indicator and Indicator Groups:

Indicator Group Property Set Type Property Set
Measurements dca.demo.sap.weatherstation:IG_Measurements IG_Measurements0
Scores dca.demo.sap.weatherstation:IG_Scores IG_Scores0

and the following mapping for the Indicators:

Indicator Property
Temperature I_Temperature
Pressure I_Pressure
Humidity I_Humidity
Score I_Score
Normalized_Score I_Normalized_Score

Make sure to replace the IDs in this blog post with the IDs of your system!

Get a JWT token for Authentication and Authorization

The easiest way to authenticate and authorize against Leonardo IoT is to use the service key. There is good description how to get the service key in this help article.

Once you have obtained the clientId and clientSecret for your Leonardo IoT tenant we can do a curl request do retrieve a so-called JWT token from the SAP UAA. As in the other blog posts, we will store the JWT token in the headers.txt file to use it later in our requests to the Leonardo IoT APIs. In the following call replace the placeholders (<tenant-subdomain>, <clientId>, <clientSecret>) with the actual values taken from your service keys:

curl -X POST \
  https://<tenant-subdomain>.authentication.eu10.hana.ondemand.com/oauth/token \
  -H 'content-type: application/x-www-form-urlencoded' \
  -d 'grant_type=client_credentials&response_type=token&client_id=<clientId>&client_secret=<clientSecret>' | jq -r '.access_token' | sed 's/^/Authorization: Bearer /' > headers.txt

After sending this request, your headers.txt should somehow similar like this:

➜  ~ cat headers.txt
Authorization: Bearer eyJhbGciOiJSUzI1NiIsImprdSI6Imh0dHBzOi8vZGNhLWRlbW8tbGl2ZS5hdXRoZW50aWNhdGlvbi5ldTEwLmhhbmEub25kZW1hbmQuY29tL3Rva2VuX2tleXMiLCJraWQiOiJrZXktaWQtMSIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI1YjM5MmVmMjMyYWE0YjRmYmZlYjg3YTk0ODgwMTA0NCIsImV4dF9hdHRyIjp7ImVuaGFuY2VyIjoiWFNVQUEiLCJ6ZG4iOiJkY2EtZGVtby1saXZlIiwic2VydmljZWluc3RhbmNlaWQiOiIzNWU4MGQyMS0xOGQxLTRjYmEtYjZiYS05NDRmMzhlMzE5MDcifSwic3ViIjoic2ItMzVlODBkMjEtMThkMS00Y2JhLWI2YmEtOTQ0ZjM4ZTMxOTA3IWIxNDY3MXxpb3RhZV9zZXJ2aWNlIWI1IiwiYXV0aG9yaXRpZXMiOlsiYXV0aCF0NS5jb25mLmMiLCJhdXRoIXQ1LmNvbmYuZCIsInRnIXQ1LnUiLCJ0ZW5hbnQhdDUucGVycy5jIiwidGhpbmchdDUuRXZlbnQuciIsInRlbmFudCF0NS5wZXJzLmQiLCJ0aGluZyF0NS5FdmVudC51IiwidGchdDUuciIsImF1dGghdDUuY29uZi5yIiwidGchdDUuYyIsInRnIXQ1LmQiLCJjb25mIXQ1LnIiLCJ0ZW5hbnQhdDUucGVycy5yIiwidGVuYW50IXQ1LnBlcnMudSIsInVhYS5yZXNvdXJjZSIsImNvbGRzdG9yZSF0NS5yIiwiaW90YXMhdDUuQXNzaWdubWVudC5yIiwiYmRtIXQ1LnIiLCJpb3RhcyF0NS5Bc3NpZ25tZW50LmMiLCJpb3RhcyF0NS5Bc3NpZ25tZW50LmQiLCJvaHMhdDUudSIsImJwIXQ1LmMiLCJvaHMhdDUuciIsImJwIXQ1LmQiLCJpb3RhcyF0NS5nZW9sb2NhdGlvbi5yIiwiaW90YXMhdDUuVm9jYWJ1bGFyeS5yIiwidGhpbmdjb25mIXQ1LmQiLCJpb3RhcyF0NS5BTS5jIiwiaW90YWVfc2VydmljZSFiNS5DYWxsYmFjayIsInRoaW5nY29uZiF0NS5jIiwiaW90YXMhdDUuQU0uZCIsImJwIXQ1LnZoLnIiLCJhdXRoIXQ1LmMiLCJpb3RhcyF0NS5Wb2NhYnVsYXJ5LnUiLCJ0aGluZyF0NS5kIiwiaW90YXMhdDUuZ2VvbG9jYXRpb24uZCIsInRoaW5nIXQ1LmMiLCJicCF0NS5yIiwiaW90YXMhdDUuQXNzaWdubWVudC51IiwiY29tcGNkIXQ1LnIiLCJicC...

After a while, the JWT will expire and you have to run the above command again.

Get Sensor Data for Indicator Group ‘Measurements’

Generally to view or upload data we have to use the appiot-mds service of Leonardo IoT.

To retrieve the data for Thing ‘CF1446EF0F3B481684E3F1E1A391E182’ of ThingType ‘dca.demo.sap.weatherstation:M_Weather_Station’ and PropertySet ‘IG_Measurements0’ in the time range from 2019-06-01T00:00:00Z to 2019-06-02T00:00:00Z we can send the following request:

 

curl -H @headers.txt -s \
"https://appiot-mds.cfapps.eu10.hana.ondemand.com/Things('CF1446EF0F3B481684E3F1E1A391E182')/dca.demo.sap.weatherstation:M_Weather_Station/IG_Measurements0?timerange=2019-06-01T00:00:00Z-2019-06-02T00:00:00Z" | jq .

Response:
{
  "value": []
}

 

The response indicates that there is no data ([]) available for that time range. Let’s upload our first entry πŸ™‚

Upload Sensor Data

The payload for two example sensor readings is in the snippet below. Feel free to modify the date in the ‘_time’ property of the readings. Especially when you get a respond from the API that “_time cannot be beyond retention period”. This means that the timestamp of the sensor data are not in the retention period of the time series store. In that case, use more recent dates (easy) or adjust the retention period in Leonardo IoT.

{
   "value":[
      {
         "_time":"2019-06-01T01:00:00Z",
         "I_Temperature":1,
         "I_Pressure":2,
         "I_Humidity":3
      },
      {
         "_time":"2019-06-01T02:00:00Z",
         "I_Temperature":4,
         "I_Pressure":5,
         "I_Humidity":6
      }
   ]
}

The following curl command uploads it:

curl -X PUT \
-H @headers.txt \
-H 'Content-Type: application/json' \
"https://appiot-mds.cfapps.eu10.hana.ondemand.com/Things('CF1446EF0F3B481684E3F1E1A391E182')/dca.demo.sap.weatherstation:M_Weather_Station/IG_Measurements0" \
-d '{
  "value": [
  {
        "_time": "2019-06-01T01:00:00Z",
        "I_Temperature": 1,
        "I_Pressure": 2,
        "I_Humidity": 3
  },
  {
        "_time": "2019-06-01T02:00:00Z",
        "I_Temperature": 4,
        "I_Pressure": 5,
        "I_Humidity": 6
  }
  ]
}'

We can check if data is uploaded by executing the command from above again:

➜  ~ curl -H @headers.txt -s \
"https://appiot-mds.cfapps.eu10.hana.ondemand.com/Things('CF1446EF0F3B481684E3F1E1A391E182')/dca.demo.sap.weatherstation:M_Weather_Station/IG_Measurements0?timerange=2019-06-01T00:00:00Z-2019-06-02T00:00:00Z" | jq .

Response:
{
  "value": [
    {
      "_time": "2019-06-01T02:00:00.000Z",
      "I_Temperature": 4,
      "I_Humidity": 6,
      "I_Pressure": 5
    },
    {
      "_time": "2019-06-01T01:00:00.000Z",
      "I_Temperature": 1,
      "I_Humidity": 3,
      "I_Pressure": 2
    }
  ]
}

Which now returns the data we uploaded!

Verify Data in PdMS

When we now go to the PdMS Equipment page of this Equipment and open the Indicator Chart, we see that our two readings have been uploaded. It can take a few moments for them to appear, because Leonardo IoT computes M4 aggregates to be able to visualise large quantity of data.

Delete Sensor Data

The Delete request is similar to the Get request, just that a different Http-Verb is used:

curl -H @headers.txt -X DELETE -s \
"https://appiot-mds.cfapps.eu10.hana.ondemand.com/Things('CF1446EF0F3B481684E3F1E1A391E182')/dca.demo.sap.weatherstation:M_Weather_Station/IG_Measurements0?timerange=2019-06-01T00:00:00Z-2019-06-02T00:00:00Z"

When you now Refresh the Indicator Chart or send the Get request to the API again, the data should be gone:

 

To upload larger amount of data is advisable to use a scripting language like Python to construct the payload for the API.

 

That concludes this part of the blog post series, in which you have seen how to bring sensor data into PdMS through Leonardo IoT.

9 Comments
You must be Logged on to comment or reply to a post.
  • Hello Nicolas

    Thank you very much for the third part of the series. I like the Leonardo IoT API quite much, as it is way more intuitive than the PdMS API. Now, by pure luck I found the following statement in the PdMS documentation:

    “The new times series APIs based on Asset Central Foundation (ACF) data model and terminology will replace the native SAP Leonardo IoT times series APIs in SAP Predictive Maintenance and Service (PdMS), scenarios, over the next releases. In a case, direct consumption of SAP Leonardo IoT time series APIs is unavoidable, provisions should be made for adaptation and/or migration to new API in future.”

     

    How future safe is it to go the Leonardo IoT way, instead of using the native APIs?

    • Hi Matthias,

      thanks for reading and commenting!

      I asked internally and got the following answer “we will make every effort to have minimum impact in terms of adaption for the customer. Adequate help and how to documents would be provided for easier switch to reduce the risk of development.”

      Best Regards,

      Nicolas

  • Hello Nicolas,

     

    Thank you for your blog posts! πŸ™‚

    I hope you can help me maybe. I have now created datasets, configured models and trained models. Is it possible to delete values ​​created by scoring? I also tried to delete a model, but the values ​​are still visible in the monitoring.

    • Hi Wilhelm,

      good job πŸ™‚

      If you want to delete the scores you need to do it as in chapter “Delete Sensor Data”, just that you pick the indicators / indicator groups from your output mapping of the model. There is currently no “convenient” functionality to delete scores when a model is deleted.

      Nicolas

  • Hello Nicolas,

    Thank you for your support.

    I want to test the Failure Prediction Using the Tree Ensemble Classifier (TEC), however, the SAP support page indicates that the data requires preparation.

    On SAP Support Site β€œhttps://help.sap.com/viewer/f50a0b24de8e4968a683e6f926bf1563/1902/de-DE/2da515c1b1c740799cb520063f97f7cd.htmlβ€œ Β I read following part and I Have 2 or 3 Questions for this part:
    “This means that the training data contains a column that indicates for each record whether it belongs to a regular or a faulty system.”

    Where can I specify which column it is? Is this about independent or dependent variables?

    Is a simple Boolean or String sufficient?

    Many thanks in advance for your reply.

    • Hi Wilhelm,

      there are two ways here, with b) being the preferred one:

      a) Use a numeric indicator and upload 0 (healthy) or 1 (faulty) values. In the Dataset Configuration add this indicator and in the model configuration use it as dependent variable. Note that Boolean or String indicators are not supported currently.

      b) Use Labelling: Upload Alerts or Notifications for the equipment at the point of failure. In the Dataset Configuration, use the Labels feature to add labels to your Dataset Configuration with appropriate lead time and prediction window. In Model configuration, use ‘label’ as dependent variable.

      Please try it out and revert back in case of questions.

      Nicolas

      •  

        Hi Nicholas,

        Your block is really helpful to me configure our PDMS system.

        Can you please suggest me on how / where we can predict the failures based on the attachment.

        Here I set my predict window as 2 hrs. In my indicator chart the sensor values (LOR) are not predicted. Please suggest.

        Regards,

        Julian.