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 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.

3 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