[Archive] GCP IoT Core
このライブラリはアーカイブされており、サポートされなくなりました。
このライブラリは、Google Cloud IoT Coreと通信する機能を提供する組み込みクラスです。
Library usage requirements | |
---|---|
Type | Integrations |
Name | Google_IoT_Core |
Version | 2021-03-31 |
Code size used | 4.1KB |
Resources used | HTTPS x 1, MQTT x 1, Timers x 1 |
関連資料
このライブラリで使用しているGoogle Cloud IoT Core APIの詳細については、ドキュメンテーションを参照してください。
Abstracts
Methods()/Properties | Summary |
---|---|
new GOOGLE_IOT_CORE() | GOOGLE_IOT_CORE オブジェクトを、渡された設定で初期化します。 |
{GOOGLE_IOT_CORE} Instance
Methods()/Properties | Summary |
---|---|
.buildGrpcUrl() | 指定された設定からgRPCへのコード変換を使用し、URLを作成します。 |
.makeDeviceJWT() | GCPで使用する有効なJWTを作成します。 詳細はJWT ドキュメントを参照してください。 |
.httpPost() | Google Cloud IoT REST Device APIにPOSTリクエストを送信します。イベントの送信またはデバイス設定の更新については、 HTTP経由での公開 を参照してください。 |
.abortHttpRequest() | 進行中のHTTPリクエストを中止します。 |
.mqttConnect() | GCP IoT CoreのLTS(Long-term support)ドメインに接続します。 MQTT.Client オブジェクトにClient.exPublish() とClient.mqttSubscribe() を拡張します。 |
.errors | 無効なキー名を含む配列。 無効な構成が setConfig またはコンストラクターに渡された場合にのみ存在します。 |
Details
new GOOGLE_IOT_CORE(config)
GOOGLE_IOT_CORE
インスタンスを初期化します。
Configuration
GOOGLE_IOT_CORE
オブジェクトをインスタンス化する場合に、次の設定オプションが必要です。
Name | Type | Default | Summary |
---|---|---|---|
privateKey | string | MANDATORY | デバイスの秘密鍵。使用する前に、対応する公開鍵をGoogle Cloud IoT Coreコンソールにアップロードします。有効なJavaScriptの文字列である必要があります。 - Google Cloud IoT Coreで公開鍵と秘密鍵のペアを作成する |
ca | string | MANDATORY | GCP IoT CoreとHTTP通信する際に使用するルートCA。 |
mqttCa | string | MANDATORY | GCP IoT CoreとMQTT通信する際に使用するルートCA。MQTTサーバー証明書のダウンロードを参照してください。 |
project | string | MANDATORY | GCP IoT Coreのプロジェクト |
location | string | MANDATORY | ] GCP IoT Coreのロケーション |
registry | string | MANDATORY | GCP IoT Coreのレジストリ |
device | string | MANDATORY | GCP IoT Coreのデバイス |
[timeout] | number | 90000 | デフォルトは90秒(90000ms)です。通信がタイムアウトされるまでの時間(ミリ秒単位)を指定します。HTTPリクエストの場合、リクエストが自動的にタイムアウトするまでの時間になります。 |
[tokenTimeout] | number | 3600 | デフォルトは60分(3600秒)です。 生成されたJWTが有効な時間(秒単位)を指定します。 |
config
は次の形式のJavaScriptオブジェクトである必要があります。
var config = {
privateKey: "<String>",
ca: "<String>",
mqttCa: "<String>",
project: "<String>",
location: "<String>",
registry: "<String>",
device: "<String>",
timeout: "<Number>",
tokenTimeout: "<Number>",
};
設定オブジェクトが作成されると、インスタンスの作成時に GOOGLE_IOT_CORE
に渡すことができます。無効な値が渡された場合、setConfig
の結果はerrors
プロパティに格納されるため、適切に処理する必要があります。
var iot = new GOOGLE_IOT_CORE(config);
if ('errors' in iot) {
// TODO: handle errors
}
Setter Methods
GOOGLE_IOT_COREインスタンスを作成後、それぞれの設定は、対応するセッターメソッドによって変更できます。無効な値がいずれかのセッターに渡されると、 false
が返されます。
Setter | Summary |
---|---|
.setPrivateKey(value: string) | デバイスの秘密鍵を設定します。使用する前に、対応する公開鍵をGoogle Cloud IoT Coreコンソールにアップロードします。 有効なJavaScript文字列である必要があります。 - Google Cloud IoT Coreで公開鍵と秘密鍵のペアを作成する |
.setTimeout(value: number) | HTTPリクエストのタイムアウトを設定します(デフォルト:90000ミリ秒(90秒)) |
.setTokenTimeout(value: number) | JWTのタイムアウトを設定します(デフォルト:60*60*1000 ms(1時間)) |
.setProject(value: string) | RESTエンドポイントの構築に使用されるIoT Core Coreのプロジェクトを設定します。 |
.setLocation(value: string) | RESTエンドポイントの構築に使用されるIoT Core Coreのロケーションを設定します。 |
.setRegistry(value: string) | RESTエンドポイントの構築に使用されるIoT Core Coreのレジスターを設定します。 |
.setDevice(value: string) | RESTエンドポイントの構築に使用されるIoT Core Coreのデバイスを設定します。 |
.setRootCA(value: string) | GCP IoT CoreのHTTPのルートCAを設定します。サンプル値については、オブジェクトの使い方 を参照してください |
.setMqttCa(value: string) | GCP IoT CoreのMQTTのルートCAを設定します。サンプル値については、オブジェクトの使い方 を参照してください |
.setConfig(config)
setConfig
メソッド を用いると、複数の設定オプションを同時に設定したり変更したりすることができます。下記のようにJSONフォーマットで指定してください。無効な値が渡された場合、無効なキーの名前を含む配列を返し、その配列にerrors
プロパティを設定します。 有効な config
がsetConfig
に渡され、errors
が存在する場合、それは削除されます。
iot.setConfig({
privateKey: "value",
ca: "value",
project: "value",
location: "value",
registry: "value",
device: "value"
});
Instance Methods
.buildGrpcUrl()
指定された設定からgRPCへのコード変換を使用し、URLを作成します。
Name | Type | Default | Summary |
---|---|---|---|
return | string | - | gRPC URLを含む projects/[PROJECT]/locations/[LOCATION]/registries/[REGISTRY]/devices/[DEVICE] 形式の文字列を返します。 |
.makeDeviceJWT([tokenTimeout][,iat])
JSON Web Tokenの使用に従って、使用する有効なJWTを生成します。
Name | Type | Default | Summary |
---|---|---|---|
tokenTimeout | number | config.tokenTimeout | このJWTが有効な時間(秒単位) |
iat | number | (現在時刻) | JWTの発行日時(ミリ秒) |
return | string | - | JWTは有効期限が24時間のprivateKey で署名します。 |
.httpPost(jwt,path,body,callback,length)
Google Cloud IoT REST Device APIにPOSTリクエストを送信します。イベントの送信またはデバイス設定の更新については、HTTP経由の公開 を参照してください。
Name | Type | Default | Summary |
---|---|---|---|
jwt | string | MANDATORY | makeDeviceJWT で生成されるJWT |
path | string | MANDATORY | gRPCへのコード変換のパス。API v1の場合、GCP IoT CoreエンドポイントはpublishEvent (${grpcUrl}:publishEvent )、または setState (${grpcUrl}:setState )です。 |
body | string or function | MANDATORY | string: path に送信するペイロード。GCP IoT Coreは、エンドポイントの正しい形式のJSON文字列のみを受け入れます。最大ペイロードサイズは4KBです。[ver. 2021-03-31+] function: 送信するペイロードを取得するためのコールバック( body )。 データがなくなるまで4KB以下の[string/ArrayBuffer]チャンクでデータを返し、最後にnull を返します。4KBより大きいペイロードを取り扱うことができます。 |
callback(err, resp) | function | MANDATORY | 応答を処理するためのユーザーのコールバック関数。エラーを err として渡し、レスポンスを resp として渡します。 |
length | number | - | ver. 2021-03-31+body がfunction の場合で必須。 GCP IoT Core送信するデータ量になります。 |
return | undefined | - | - |
Responses
GCP IoT Coreのレスポンスは、次の形式で返します。
{
statusCode: <Number>,
statusMessage: <String>,
body: <String>
}
statusCode
と statusMessage
の詳細については、該当するデバイスのHTTPSドキュメントをご覧ください(NEQTO Bridge | Spresense)
body
はHTTPレスポンスのbodyデータです。
Errors
neqto.jsのHTTPオブジェクトのエラーを返します。
{
errCode: <Number>
}
errCode
パラメータについてはneqto.jsドキュメントをご覧ください。(NEQTO Bridge | Spresense)
.abortHttpRequest()
現在進行中のHTTPリクエストを中止します。
Name | Type | Default | Summary |
---|---|---|---|
return | undefined | - | - |
.mqttConnect(jwt,[options])
GCP IoT CoreのLTS(Long-term support)ドメインに接続します。詳細は、Using a long-term MQTT domainを参照してください。
Name | Type | Default | Summary |
---|---|---|---|
jwt | string | MANDATORY | makeDeviceJWT で生成されるJWT |
options | object | {} | 適切なMQTTのドキュメントにあるMQTTオプション。protocolId , clientId , username , password は予約語であり、上書きされます。 |
return | MQTT.Client | - | GCP IoT Coreに接続されたMQTTインスタンス。このオブジェクトの詳細については、デバイスの適切なMQTTページを参照してください。 - NEQTO Bridge - Spresense |
MQTT.Client Methods
Methods()/Properties | Summary |
---|---|
Client.exPublish() | /devices/${device}/${dest} にパブリッシュします。「event」と「state」のみが有効なオプションです。 |
Client.mqttSubscribe() | /devices/${device}/${dest} をサブスクライブします。オプションの「config」と「commands/#」だけが有効なエンドポイントです。 |
.exPublish(dest,message[,options][,callback])
/devices/${device}/${dest}
にパブリッシュします。「event」と「state」のみが有効なオプションです。
Name | Type | Default | Summary |
---|---|---|---|
dest | string | MANDATORY | 「event」または「state」のみ |
message | string | MANDATORY | 文字列としての必要なイベントまたはstateデータ |
options | object | {"qos" : 0} | 詳細はMQTT ドキュメント を参照してください。 |
callback | function | - | NEQTO MQTT ドキュメントを参照してください。 |
return | boolean | - | パブリッシュを試みた場合は true 。それ以外の場合は false 。 応答は callback に返されます。 |
.exSubscribe(dest[,options][,callback])
/devices/${device}/${dest}
をサブスクライブ。オプションの「config」と「commands/#」だけが有効なエンドポイントです。MQTTクイックスタートドキュメントのNodeJSの例を参照してください。
Name | Type | Default | Summary |
---|---|---|---|
dest | string | MANDATORY | 「config」または「commands/#」。 |
options | object | {"qos": 0} | 詳細はMQTT ドキュメント を参照してください。 |
callback | function | - | NEQTO MQTT ドキュメントを参照してください。 |
return | boolean | - | サブスクライブを試行できた場合は true 。それ以外の場合は false 。 応答は callback に返されます。 |
Usage Examples
config
オプションで使用できる CA
の取得方法はこちら。
ルートCAがターゲットのGCP IoT Coreエンドポイントに適切であることを確認してください。
var gcpIotCa = '-----BEGIN CERTIFICATE-----\n...<CA>...\n-----END CERTIFICATE-----';
var mqttMinCa = '-----BEGIN CERTIFICATE-----\n...<CA>...\n-----END CERTIFICATE-----';
次のコードは、以降のサンプルコードの先頭に入ります。全ての設定を適切に置き換えて使用してください。
// IMPORTED LIBRARIES
// - Google_IoT_Core
// Logging setup
log.setLevel(0,2); //-1:NONE 0:ERROR 1:WARNING 2:DEBUG 3:TRACE, 0:DISABLE 1:LOG 2:CONSOLE 3:BOTH
log.printLevel(2); //0:DISABLE 1:LOG 2:CONSOLE 3:BOTH
// Set configurations
var config = {
privateKey: "<String>",
project: "<String>",
location: "<String>",
registry: "<String>",
device: "<String>"
};
var iot = new GOOGLE_IOT_CORE(config);
if ('errors' in iot) {
// TODO: Handle errors
throw 'Invalid configuration'
}
Sample 1: 基本的なHTTPSの使用法
iot.setRootCA(gcpIotCa);
var host = iot.buildGrpcUrl();
var payload = secure.base64Encode("Publishing via HTTP");
var callback = function(err, resp) {
if (err) {
print(JSON.stringify(err));
}
if (resp) {
print(JSON.stringify(resp));
}
}
var body = {
"binary_data": payload
}
var jwt = iot.makeDeviceJWT(3600); //update JWT each connection. 3600 == 1 hour.
iot.httpPost(jwt, `${host}:publishEvent`, JSON.stringify(body), callback);
Sample 2: HTTPでデータを分割送信します
iot.setRootCA(gcpIotCa);
var host = iot.buildGrpcUrl();
// This simulates a large payload.
// In a production environment, this may be collected data from attached devices.
var sensorData = "";
while (sensorData.length < 4096) {
sensorData += sensorData.length.toString();
}
// See the Secure object documentation for possible limitations.
var encodedData = secure.base64Encode(sensorData);
var payload = JSON.stringify({
"binary_data": encodedData
});
var callback = function(err, resp) {
if (err) {
print(JSON.stringify(err));
}
if (resp) {
print(JSON.stringify(resp));
}
}
// body must be a function that returns data in chunks until exhausted, then returns null
var returnedDataChunks = 0;
var body = function() {
var retSize = payload.length / 8;
if (returnedDataChunks < 8) {
return payload.slice(returnedDataChunks++ * retSize, returnedDataChunks * retSize)
} else {
return null;
}
}
var jwt = iot.makeDeviceJWT(3600); //update JWT each connection. 3600 == 1 hour.
// [length] parameter is needed because body is a function
iot.httpPost(jwt, `${host}:publishEvent`, body, callback, payload.length);
Sample 3: トークンの有効期限が切れた場合のMQTTでの再接続
iot.setMqttCa(mqttMinCa);
var reconnectAttempts = 0;
var client;
var reconnectSt = 0; //0: No reconnect, 1: Reconnect backoff, 2: Expired backoff(available reconnect)
var scheduleMqttReconnect = function() {
if(reconnectSt) {
return;
}
reconnectSt = 1; //waiting reconnect
var backoff = 64 * 1000; //backoff[msec]
reconnectAttempts++;
//Notice: This example updates the JWT for each connection.
// You may want to check the token timeout and update the JWT.
// [Refer](https://cloud.google.com/iot/docs/how-tos/credentials/jwts#required_claims)
if(client) {
client.end(); // close the connection, free resources
client = undefined; // destroy the current client
}
print('Reconnect backoff[ms]:' + backoff);
setTimeout(function() {
print('Backoff expired');
reconnectSt=2;
}, backoff);
}
var registerEventHandlers = function() {
if(!client){
print('skip registerEventHandlers()');
return; // quit
}
client.on('connect', function() {
reconnectAttempts = 0;
if(client.isConnected()){
var rc = client.exSubscribe('config', { qos : 1 }, function(err) {
if(err.code != 0){
print('exSubscribe() failed');
//TODO: Error Handling. (Reconnect is recommended)
}
});
if(!rc) {throw 'subscribe topic failed';}
var rc = client.exSubscribe('commands/#', { qos : 1 }, function(err) {
if(err.code != 0){
print('exSubscribe() failed');
//TODO: Error Handling. (Reconnect is recommended)
}
});
if(!rc) {throw 'subscribe topic failed';}
}
});
client.on('error', function(err) {
print('mqttClientOnError: ' + err.code);
if(err.code == 1) { // 1: connection failed
var errnoConnect = client.get('errnoConnect');
print('errnoConnect ' + errnoConnect);
scheduleMqttReconnect();
} else {
//TODO: Error Handling.
}
});
client.on('message', function(topic, message) {
print('TOPIC ' + topic);
print('MESSAGE ' + message);
//TODO: Message Handling
});
client.on('close', function() {
print('DISCONNECTED');
scheduleMqttReconnect();
});
}
var publishInterval = 60 * 1000;
var publishEvent = 0;
setInterval(function() {
publishEvent = 1;
}, publishInterval);
// Main loop
reconnectSt = 2;
while(1) {
if(reconnectSt == 2) { //Allow MQTT connection
reconnectSt = 0;
if(!client) {
var jwt = iot.makeDeviceJWT(3600); //update JWT each connection. 3600 == 1 hour.
client = iot.mqttConnect(jwt);
if(!client) {
scheduleMqttReconnect();
} else {
registerEventHandlers();
}
} else {
client.reconnect();
}
}
if(client && client.canPublish()) {
if(publishEvent) {
publishEvent = 0;
client.exPublish('event', 'Publishing over MQTT', { qos : 1 }, function(err) {
if(err.code == 0) {
print('publish success');
} else {
print('publish failure ' + err.code);
}
});
}
}
}