Commands in SAP IoT Application Enablement
Introduction
Since release 1.46 SAP IoT Application Enablement provides a feature to send commands from Application Enablement directly to your device. Therefore, Application Enablement can not only store your thing data now, it can be the control center for your IoT scenarios. There is a strong demand for this features in a lot of use cases. In this blog post, we will get you up and running with this new feature.
Prerequisites
- A tenant for SAP IoT Application Enablement
- A tenant for SAP Cloud Platform Internet of Things for the Cloud Foundry Environment (IoT S)
- Both tenants must be connected
Scenario
We are going to model a robot with one component, the robot arm. The goal is to send a command to the hydraulics of this robot arm.
The command will be send to Application Enablement. Application Enablement will forward the request to the SAP Cloud Platform Internet of Things for the Cloud Foundry Environment, which will send the command to the device via MQTT [1].
Tenant configuration
At first, we must register and authenticate our IoT Services tenant as a provider for sensor data in Application Enablement. We can do this with the help of the API of Application Enablement [1]:
POST /tm-data-mapping/credentials
{
"provider": "IoTServices4",
"user": "< root user>",
"password": "<root secret>",
"host": "<host>"
}
Please make sure that you enter the host without the protocol “http://” . For instructions on how to use the API of Application Enablement please read the referenced blog post [2].
Device onboarding
Next, we will onboard our physical device in SAP Cloud Platform Internet of Things for the Cloud Foundry Environment. At first, we will create two capabilities for our device. Both will represent the Arm of our robot: the first one represents the time series data of the arm, the second one represents the commands sent to the arm. For now, it´s important that both capabilities representing the arm have the same name and the same structure. Only the ID and the alternate ID should be different. You can create both with the following API calls:
POST /iot/core/api/v1/capabilities
{
"name" : "Arm",
"properties" : [
{
"name" : "Hydraulics",
"dataType" : "float"
}
]
}
POST /iot/core/api/v1/capabilities
{
"name" : "Arm",
"properties" : [
{
"name" : "Hydraulics",
"dataType" : "float"
}
]
}
Please note down the id of both capabilities.
Now, we are going to bring both capabilities together in one SensorType:
POST /iot/core/api/v1/sensorTypes
{
"name" : "Robot-Sensor",
"capabilities" : [
{
"id" : "<capability id measure>",
"type": "measure"
},
{
"id" : "<capability id command>",
"type": "command"
}
]
}
Please note down the id of your sensor type.
Finally, we can create our robot device and attach a sensor for our robot arm to this device:
POST /iot/core/api/v1/devices
{
"gatewayId" : "<mqtt gateway id>"
"name": "Robot_ThingShadow"
}
POST /iot/core/api/v1/sensors
{
"deviceId" : "<your device id>",
"sensorTypeId" : "<your sensor type id>",
"name": "Robot-Arm-Sensor"
}
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.
At first, we must create and configure a package for our robot. We can do this via the Configuration API of Application Enablement [3]. Our package must include three important entities for this scenario:
- A PropertySet for the robot arm with a property Hydraulics. We will send commands to this property hydraulics of our arm at the end of the blog post.
- A ReferencePropertySet for this robot arm: This reference property set will “shadow” our PropertySet and will store all commands. Within this shadow we will define a property type of attribute type com.sap.iot.core.Command to send a desired value to our robot device modeled in IoT Services. When we update or change the value of the property type, the command will be send to our device.
- A ThingType for our robot, which includes our shadowed PropertySet robot arm.
A package with the above described configuration is created by the following API call. Please make sure that you replace “sap.iotrig” with the name of your tenant.
POST /appiot-mds/appcore-conf/Configuration
Payload: https://gist.github.com/LukasBrin/6f6d9d18cf42e7de17e38d4d8d3b0025
Next, we will go to the thing modeler and create a thing there. At first, please familiarize yourself with the created ThingType Robot in the package thingshadow. You will see, that our robot type has a command field in the property Hydraulics.
Now we will create our robot thing. Add the following configuration to your new thing:
Please make sure, that you select the device and senor created in a previous step as well as your own authorization group. You should see the mapping of thing and device like this:
Please note down the id of your thing.
First Validation
To check if everything works as expected, we will send and receive commands via the User Interface now.
To send a command, go to your thing and add a command in the provided input field:
When you click the save button, the command will be sent to our device. To validate, that the command arrived in IoT services we will have a look at the command logs in the IoT Services cockpit classic.
Open the following url: https://<your iot s host>/iot/cockpit-classic/
Select the “command logs” in the panel on the left and sort the table descending by the timestamp:
The result will be a table like this, which should include a command. You can identify this command with the “sendCommand” entry in the column “API”.
If you can see such a command entry here, everything looks fine up to this point. If not, please go through the steps again and make sure that you have executed all the described steps.
In the next steps, we are going to send a command via the API as you don´t want to send command out of the ThingModeler in a productive scenario. We will then subscribe to commands sent to our device´s MQTT gateway.
Sending commands
Furthermore it´s possible to send commands via the API of Application Enablement, e.g. to trigger the command automatically from another system when a condition is fulfilled. This can be achieved with the following API call. Please add your thing id, replace “sap.iotrig” with your tenant and update the time stamp to the current time.
PUT /appiot-mds/Things('<your thing id>')/ReferenceProperties/sap.iotrig.thingshadow:Robot/Arm
{
"value": [{
"Command67428": "2",
"_time": "2017-12-20T13:20:34Z"
}]
}
This call will send the command “2” to the created in the previous steps device.
Subscribing to commands
In this tutorial, we will use our laptop as a device. For this kind of task, a program called paho client is available [4]. Please install the program now and come back to this blog post afterwards. Now, we will subscribe our laptop to the commands-topic of our device to demonstrate the receipt of a command. In a real use case you would subscribe your device to this commands-topic and trigger an action when you receive a command. Please create a new Paho connection and set the following configurations:
Server URI: ssl://<your iot s host>:8883
Client Id: <your device alternate id>
Enable ssl [x]
Key store location: <reference the certificate of your device (*.ks)
Key store password: <password from the pswd.properties>
Trust store location: <reference to your java keystore, e.g. “C:\Program Files\Java\jre1.8.0_151\lib\security\cacerts”>
Trust store password: “changeit”
You can download the certificate of your device directly from the Cockpit of SAP Cloud Platform Internet of Things for the Cloud Foundry Environment.
Next, connect to the system and enter the topic “commands/<your device alternate id>” to your subscriptions. Your connection should look like this afterwards:
Now, try to trigger a command with the help of the Application Enablement API again. You should see an additional entry in the history on the right side with the event type “Received”. A double click on this entry will open a view with all details of the received command:
In a real world scenario, you would subscribe your device to this MQTT topic and trigger an action in case a specific command arrives.
Summary
That´s it! I hope you could follow all the explained steps and got an overview of the new capability of SAP IoT Application Enablement. Feel free to ask your questions in the comments.
[1] https://www.hivemq.com/blog/how-to-get-started-with-mqtt
[3] https://blogs.sap.com/2017/10/13/access-the-sap-iot-application-enablement-apis-using-postman/
[5] https://www.eclipse.org/paho/
hi Lukas,
Great Blog. Thank you for sharing.
Best Regards,
Venu
Hi @lukas.brinkmann,
short question as described in the release (Version 1.46) notes from IoT AE link
"The attribute type com.sap.iot.core.Command for reference property is renamed as com.sap.iot.core.TargetValue."
The property must be adapt, to the new one?
br,
fabian
Hi Fabian Lehmann,
currently both attribute types are supported, but the type "com.sap.iot.core.TargetValue" is recommended. "com.sap.iot.core.Command" is deprecated was removed from the documentation.
Best regards,
Lukas
Hi Lukas,
Would it also be possible to create the "ReferencePropertySet" in the Thing Properties Catalog? Or do we need to use the api for that?
Kind regards, Wouter
Hi Wouter,
as far as I know, it´s only possible via the API.
Best regards,
Lukas
Tried all steps mutliple times but I'm not getting any result in the command log... any ideas?
I had to logon to the iot cockpit with the root user to see the command.
Hi Lukas,
I folloved your instructions, but no commands were published. Both Paho mqtt tool and python mqtt client show nothing.
Is this blog still up to date? There is no command log in the current version of IoT Cockpit.
Are the commands that where send by AE saved somewhere? In my opinion a command sending can be seen as an event, why not store it in the event list?
Hi everyone,
for OData-based Thing-Modeler there's an offical SAP-Learning Journey, have fun:
https://developers.sap.com/tutorials/iot-express-2-create-device-model.html
Hi Lukas,
Thank you for writing this blog. I think I know have found the needle in a haystack to connect our two tenants (tenant for SAP IoT Application Enablement and tenant for SAP Cloud Platform Internet of Things for the Cloud Foundry Environment).
But I tried both way's to "POST /tm-data-mapping/credentials".
With Postman I'm getting the bearer token an with this I'm posting the tenant configuration like you described.
But I always get the message: "IoT Credentials are not valid"
Same with the https://api.sap.com
The root credential and the host are right, because I can log in with them to the Internet of Things Service Cockpit.
Do you have any idea?
Kind regards
Silvio
I found the solution by myself.
It didn't worked with the root user. So I tried it with the tenant user - and that worked finally.
Hello Silvio - Could you please describe the solution in detail . Appreciate if you explain step byy step .
Regards~
Vivek Gupta
Hi Vivek,
There are two ways. First with Postman - described in referenced blog post [3]. And second with the SAP API Business Hub. I'll describe the latter step by step.
And as I've written, in my case it didn't worked with the root user, so I took the administrator user of my tenant, that I created.
I hope this will help you.
Kind regards
Silvio
Thanks Silvio .... Will check and let you know ..~
The documentation mentioned in this article to create the credentials might not be accurate anymore.
If you use a Leonardo IoT instance that's been created ~2019 - now, this documentation is the right one.
Also, to my knowledge this method doesn't not work currently. Correct me if im wrong.