[Archive] SAP Cloud Platform Internet of Things
このライブラリはアーカイブされており、サポートされなくなりました。
このスニペットは、SAP Cloud Platform Internet of ThingsにIoTデータを送信する機能を提供します。
Resources used: HTTPS x 1
or MQTTS x 1
Details
send_sap
関数は、HTTPS経由のREST APIを使用して、渡されたセンサーデータオブジェクトをSAP IoT deviceの「sensor capability」に「payload」を POST します。結果(エラー/レスポンス)は、コールバック関数に渡されます。
mqtt_sap
関数は、SAP IoT MQTTブローカーに接続されたMQTTクライアントオブジェクトを返します。 ユーザーはクライアントを使用して、MQTTS経由でSAP IoT デバイストピックにパブリッシュ/サブスクライブ できます。
このスニペットを使用するには、 HOST
(SAP Cloud IoTのインスタンスのホストネーム)、 DEVICE_ALTERNATE_ID
(デバイスの代替ID)、 CERT
(デバイスの証明書)、 KEY
(暗号化されていない秘密鍵)と CA
をユーザーが設定する必要があります。
SAP IoTデバイス管理ページからダウンロードした証明書には、証明書とデフォルトで暗号化されている秘密鍵の両方が含まれています。 このスニペットで使用するには、パスワードを秘密鍵から削除する必要があります。 これは、openSSL で次のコマンドを使用して実行できます。
openssl rsa -in encrypted_privatekey.pem -out un-encrypted_privatekey.pem
注意: 提供されている関数では、最大4KBまでのデータを取り扱うことができます。より大きなサイズのデータを取り扱う場合は、neqto.jsドキュメントのhttpsオブジェクト、分割書き込みを参考にしてください。
CAの取得方法はこちら。
var CA = "-----BEGIN CERTIFICATE-----\n...<CA>...\n-----END CERTIFICATE-----"
HTTPS (REST)
//=================================================================
// SAP HTTP SNIPPET
//=================================================================
//=================================================================
// The following configuration are MANDATORY. Set by user.
//=================================================================
// The address of the SAP Cloud Internet of Things instance.
var HOST = '<YOUR_HOST>';
// Alternate ID of the device.
// eg. xxxxxx
var DEVICE_ALTERNATE_ID = '<YOUR_DEVICE_ALTERNATE_ID>';
// The public certificate part of the device certificate obtained from the device management page.
// eg. '-----BEGIN CERTIFICATE-----\n...<CERT>...\n-----END CERTIFICATE-----'
var CERT = '<YOUR_CERT>';
// The private key part of the device certificate (un-encrypted) obtained from the device management page.
// eg. '-----BEGIN RSA PRIVATE KEY-----\n...<KEY>...\n-----END RSA PRIVATE KEY-----'
var KEY = '<YOUR_KEY>';
// Public certificate of the certificate authority that signed the SAP server certificate for SSL/TLS handshake.
// eg. '-----BEGIN CERTIFICATE-----\n...<CA>...\n-----END CERTIFICATE-----'
var CA = '<YOUR_CA>';
//=================================================================
/**
* Post data to SAP Cloud Internet of Things using client based authentication.
* https://developers.sap.com/tutorials/iot-cf-send-data-rest.html
* @function send_sap
* @param {number} sensorAlternateId - Alternate ID of the sensor, as a Number.
* @param {number} capabilityAlternateId - Alternate ID of the capability, as a Number.
* @param {Array} payload - The data to be sent to SAP, as either an Array of arrays of specified measures, or as an Array of JSON objects where the name of each property defined in the capability is the key.
* @param {function} callback - User callback to return the result (error/response).
* @returns {undefined}
*/
var send_sap = function (sensorAlternateId, capabilityAlternateId, payload, callback) {
var body = JSON.stringify({
"sensorAlternateId": sensorAlternateId,
"capabilityAlternateId": capabilityAlternateId,
"measures": payload
});
var options = {
"method": 'POST',
"host": HOST,
"path": `/iot/gateway/rest/measures/${DEVICE_ALTERNATE_ID}`,
"headers": {
"Content-Type": 'application/json',
"Content-Length": body.length.toString()
},
"cert": CERT,
"key": KEY,
"ca": CA
};
var request = https.request(options, function (response) {
response.on('end', function () {
callback(null, { "statusCode": response.statusCode, "statusMessage": response.statusMessage, "body": response.read() });
});
});
request.on('error', function () {
callback({ "errCode": request.errCode }, null);
});
request.end(body.toString(), function () {
print("[request] SUCCESS");
});
}
MQTTS
//=================================================================
// SAP MQTT SNIPPET
//=================================================================
//=================================================================
// The following configuration are MANDATORY. Set by user.
//=================================================================
// The address of the SAP Cloud Internet of Things instance.
var HOST = '<YOUR_HOST>';
// Alternate ID of the device.
// eg. xxxxxx
var DEVICE_ALTERNATE_ID = '<YOUR_DEVICE_ALTERNATE_ID>';
// The public certificate part of the device certificate obtained from the device management page.
// eg. '-----BEGIN CERTIFICATE-----\n...<CERT>...\n-----END CERTIFICATE-----'
var CERT = '<YOUR_CERT>';
// The private key part of the device certificate (un-encrypted) obtained from the device management page.
// eg. '-----BEGIN RSA PRIVATE KEY-----\n...<KEY>...\n-----END RSA PRIVATE KEY-----'
var KEY = '<YOUR_KEY>';
// Public certificate of the certificate authority that signed the SAP server certificate for SSL/TLS handshake.
// eg. '-----BEGIN CERTIFICATE-----\n...<CA>...\n-----END CERTIFICATE-----'
var CA = '<YOUR_CA>';
//=================================================================
/**
* Create an MQTT Client connected to SAP Cloud Internet of Things using client based authentication.
* https://developers.sap.com/tutorials/iot-cf-send-data-mqtt.html
* @function mqtt_sap
* @param {object} options - MQTT Configuration for connecting to the broker, as an Object.
* @returns {(Client|undefined)} - {Client} : Generated MQTT {Client} | undefined : {Client} generate failed due to invalid arguments or insufficient resources.
*/
var mqtt_sap = function (options) {
mqtt.set('ssl.ca', CA);
mqtt.set('ssl.key', KEY);
mqtt.set('ssl.cert', CERT);
return mqtt.connect(`mqtts://${HOST}:8883`, options);
}
Function Usage Example
Sample 1
これはsend_sap
関数を使用してサーバーにデータを送信するサンプルです。
/*
<INSERT ABOVE SNIPPET HERE WITH SET CONFIGURATIONS>
*/
//=================================================================
log.setLevel(-1); //-1:NONE 0:ERROR 1:WARNING 2:DEBUG 3:TRACE
log.printLevel(2); //0:DISABLE 1:LOG 2:CONSOLE 3:BOTH
//=================================================================
// MAIN SCENARIO
//=================================================================
/**
* Callback to fetch error/response from the request.
* @function callback
* @param {object} err - Error returned in case of a failed request. Has one property - `errCode`.
* @param {object} data - Response returned by a successfully completed request. Has three properties - `statusCode`, `statusMessage`, and `body`.
*/
var callback = function (err, data) {
if (err) {
print("[error]", err.errCode);
} else {
print("[status]", data.statusCode, data.statusMessage);
print("[response]", data.body);
}
}
var sensorAlternateId = 123;
var capabilityAlternateId = 123456;
var payload = [
{
"testProperty": 'Hello from NEQTO Device' // "property": '<DATA>'
}
];
send_sap(sensorAlternateId, capabilityAlternateId, payload, callback);
Sample 2
これは自動再接続を有効にし、mqtt_sap
関数から返されたクライアントでパブリッシュおよびサブスクライブするサンプルです。 接続後、送受信のループバックテストを行います。
/*
<INSERT ABOVE SNIPPET HERE WITH SET CONFIGURATIONS>
*/
//=================================================================
log.setLevel(-1); //-1:NONE 0:ERROR 1:WARNING 2:DEBUG 3:TRACE
log.printLevel(2); //0:DISABLE 1:LOG 2:CONSOLE 3:BOTH
//=================================================================
// MAIN SCENARIO
//=================================================================
var sensorAlternateId = 5;
var capabilityAlternateId = 123456;
var sub_topic = `ack/${DEVICE_ALTERNATE_ID}`;
var pub_topic = `measures/${DEVICE_ALTERNATE_ID}`;
var client = mqtt_sap({
"clientId": DEVICE_ALTERNATE_ID.toString(), // MANDATORY
"reconnectCount": 1855
});
if (!client) {
throw 'Failed to create mqtt instance';
}
var registerEventHandlers = function () {
if (!client) {
return;
}
client.on('error', function (err) {
print('ERROR: ' + err.code + ' ERRNO: ' + client.get('errnoConnect'));
//TODO: Error handling
});
client.on('message', function (topic, message) {
print('TOPIC: ' + topic + ' MESSAGE: ' + message);
//TODO: Message handling
});
client.on('close', function () {
print("DISCONNECTED");
});
client.on('connect', function () {
print('CONNECTED');
client.subscribe(sub_topic, { qos: 1 }, function (err) {
if (err.code > 0) {
print('MQTT SUBSCRIBE ERROR', err.code);
//TODO: Error handling
}
});
});
};
registerEventHandlers();
setInterval(function () {
if (client.canPublish()) {
var payload = [
{
"testProperty": 'Hello from NEQTO Device' // "property": '<DATA>'
}
];
var body = JSON.stringify({
"sensorAlternateId": sensorAlternateId,
"capabilityAlternateId": capabilityAlternateId,
"measures": payload
});
client.publish(pub_topic, body, { qos: 1 }, function (err) {
if (err.code == 0) {
print('Publish OK');
} else {
print('Publish failed');
//TODO: Error handling
}
});
} else {
print('Cannot publish');
}
}, 15000);
Sample 3
これは手動で再接続をして、 mqtt_sap
関数から返されたクライアントでパブリッシュおよびサブスクライブするサンプルです。 再接続が連続して失敗した場合、インスタンスは解放され再作成されます。
/*
<INSERT ABOVE SNIPPET HERE WITH SET CONFIGURATIONS>
*/
//=================================================================
log.setLevel(-1); //-1:NONE 0:ERROR 1:WARNING 2:DEBUG 3:TRACE
log.printLevel(2); //0:DISABLE 1:LOG 2:CONSOLE 3:BOTH
//=================================================================
// MAIN SCENARIO
//=================================================================
var sensorAlternateId = 5;
var capabilityAlternateId = 123456;
var sub_topic = `ack/${DEVICE_ALTERNATE_ID}`;
var pub_topic = `measures/${DEVICE_ALTERNATE_ID}`;
var client = mqtt_sap({
"clientId": DEVICE_ALTERNATE_ID.toString() // MANDATORY
});
if (!client) {
throw 'Failed to create mqtt instance';
}
var registerEventHandlers = function () {
var reconnectAttempts = 0;
var maxReconnectAttempts = 24;
if (!client) {
return;
}
client.on('error', function (err) {
print('ERROR: ' + err.code + ' ERRNO: ' + client.get('errnoConnect'));
if (err.code == 1) { //Connection failed
if (reconnectAttempts++ < maxReconnectAttempts) {
print('reconnectAttempts:', reconnectAttempts);
client.reconnect();
} else {
print('ABORT');
reconnectAttempts = 0;
client.end(); //Release mqtt instance
client = undefined;
}
}
});
client.on('message', function (topic, message) {
print('TOPIC: ' + topic + ' MESSAGE: ' + message);
//TODO: Message handling
});
client.on('close', function () {
print("DISCONNECTED");
client.reconnect();
});
client.on('connect', function () {
reconnectAttempts = 0;
print("CONNECTED");
client.subscribe(sub_topic, { qos: 1 }, function (err) {
if (err.code > 0) {
print("MQTT SUBSCRIBE ERROR", err.code);
//TODO: Error handling
}
});
});
};
registerEventHandlers();
setInterval(function () {
if (!client) {
print('Recreating MQTT Instance');
client = mqtt_sap({
"clientId": DEVICE_ALTERNATE_ID.toString() // MANDATORY
});
registerEventHandlers();
}
if (client) {
if (client.canPublish()) {
var payload = [
{
"testProperty": 'Hello from NEQTO Device' // "property": '<DATA>'
}
];
var body = JSON.stringify({
"sensorAlternateId": sensorAlternateId,
"capabilityAlternateId": capabilityAlternateId,
"measures": payload
});
client.publish(pub_topic, body, { qos: 1 }, function (err) {
if (err.code == 0) {
print('Publish OK');
} else {
print('Publish Failed');
//TODO: Error handling
}
});
}
} else {
print('Cannot Publish');
}
}, 15000);