Skip to Content
Technical Articles

Send/Receive Command with REST on SAP IoT services for SAP BTP for the Cloud Foundry Environment

This article was written in response to a customer’s inquiry, and I wrote it because I thought that there was no detailed description in the manual and no article explaining it.

With SAP IoT services for SAP BTP for the Cloud Foundry Environment, you can receive sensor information from devices, but you can also send “commands” to devices.

The word “command” may be misleading, but what is actually sent is a string of characters. Therefore, the device side needs logic to control the actual device side from the received string.

For more information about this function, please refer to the explanation of using MQTT as a gateway.

If you read this manual and practice, you will get the idea.
To briefly explain the case of MQTT, when you send a command in a specified format to a specified URL (which includes the destination device ID) provided by SAP IoT services, it is published as a Topic on the MQTT Broker, and the Subscriber can receive it. The subscriber (device) will take some action based on the content of the received topic.
So what about using a REST gateway? In this article, I will explain how to use REST gateway.

Set up

Learning from the MQTT article, we will start with the setup. However, all you have to do is choose REST Gateway instead of MQTT Gateway as the gateway in the aforementioned article.
If you have already created the environment described in the article for MQTT, you can simply create a new device using that environment, specify REST Gateway as the Gateway, and create and set a Sensor with the Capabilities created in the MQTT environment.

Send Command

The next step is to send the command. This is the same method as MQTT. This time, I will use the function in the DOC of Device Management API as in the previous article.
Open
https://<HOST_NAME>/<INSTANCE_ID>/iot/core/api/v1/doc/
by web browser. This <HOST_NAME> an <INSTANCE_ID> are same as  Internet of Things Service Cockpit URL :
https://<HOST_NAME>/<INSTANCE_ID>/iot/cockpit/#
It would be easier to open the Internet of Things Service Cockpit in a browser and replace /iot after.
When it opens, move to the Command section.
click the “Try it out” button.
Next , Enter the parameters for each item.
Note that the Device ID, Sensor ID, and Capability ID used here are not “Alternate ID” values.

Please use the GUID value here. Enter each parameter and click the Execute button.
Verify that Command Issued successfully is returned.

Receiving commands via REST

Now, let’s take a look at how to receive this command via REST.
As in the case of receiving via MQTT, the device’s certificate is required. Please download the certificate of the device in advance. This time, I am using cURL as a client.
Since I am using a Mac, I have downloaded certificate in pem format.
Next , use cURL to receive commands in this test.
The URL to get the command is
https://<HOST_NAME>/iot/gateway/rest/commands/<DEVICE_ALTERNATE_ID>

Note we should will use Alternate id here.To use cURL, follow the instructions in the manual and execute the following command.

% curl -v -k -E ’<certificate.pem>:<secret key>’ https://<HOST_NAME>/iot/gateway/rest/commands/<DEVICE_ALTERNATE_ID>

If there are no mistakes, you should get a response like the following.

% curl -v -k -E ’<certificate.pem>:<secret key>’ https://<HOST_NAME>/iot/gateway/rest/commands/<DEVICE_ALTERNATE_ID>

* Trying 3.121.203.15:443…
* Connected to <HOST_NAME> port 443 (#0)
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /Users/<Your user>/opt/anaconda3/ssl/cacert.pem
CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Request CERT (13):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS handshake, CERT verify (15):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: C=US; ST=Pennsylvania; L=Newtown Square; O=SAP America Inc.; CN=*.eu10.cp.iot.sap
* start date: Feb 12 00:00:00 2021 GMT
* expire date: Feb 16 23:59:59 2022 GMT
* issuer: C=US; O=DigiCert Inc; CN=DigiCert TLS RSA SHA256 2020 CA1
* SSL certificate verify ok.
> GET /iot/gateway/rest/commands/<ALTERNAME_DEVICE_ID> HTTP/1.1
> Host: <HOST_NAME>
> User-Agent: curl/7.71.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: application/json;charset=UTF-8
< content-length: 113
< Strict-Transport-Security: max-age=16000000; includeSubDomains; preload;
<
* Connection #0 to host <HOSTNAME> left intact
[{“sensorAlternateId”:”10005″,”capabilityAlternateId”:”10000″,”command”:{“Speed”:50.0,”Buzzer”:true,”LED”:true}}]

If you look at the BODY section at the bottom, you will see the contents of the command that was just sent.

This will be returned as JSON, so the device side will parse this and execute the logic to take some action. In the case of this example, it would be necessary to write the logic to adjust the speed of the motor, etc. to 50, and then execute the process of turning on the buzzer and LED blablabla.

POINT

When using REST, the point is that the device needs to know if a command has been issued or not. In other words, there needs to be logic that calls the REST API from the device periodically to see if any commands have been issued.

Others

For example, first issue a command with the following parameters

Next, issue the following command to the same device.

After this, if you check with REST to see if the command has been issued, the following will be returned.

—-snip—–

* Connection #0 to host <HOST_NAME> left intact

[{“sensorAlternateId”:”10005″,”capabilityAlternateId”:”10000″,”command”:{“Speed”:50.0,”Buzzer”:true,”LED”:true}},{“sensorAlternateId”:”10005″,”capabilityAlternateId”:”10000″,”command”:{“Speed”:0.0,”Buzzer”:false,”LED”:false}}]%  

The old commands are sent along with the new commands, which are sent as an array in JSON.

As far as I have tested, this JSON array seems to be arranged in the order of command issuance. However, I couldn’t find any clear documentation, so if order of commands is important, or if there is a requirement to execute only the latest command, it may be better to add the date and time of command issuance or a number to the command to be sent so that it can be identified.

Incidentally, if the command has not been issued, the following will be returned.

* Connection #0 to host <HOSTNAME> left intact
[]

Thus, an empty JSON is returned. On the device side, please take these into account when controlling the command.

 

Summary

SAP IoT services for SAP BTP for the Cloud Foundry Environment uses the above method to handle Command via REST. Using commands, device control is also possible from the cloud side, so please try this.

 

Be the first to leave a comment
You must be Logged on to comment or reply to a post.