Cloud IoTを試してみました。Google Cloud Platform Advent Calendar 2017の二日目の記事になります。
Cloud IoT Coreは、現在パブリックβということで、今後仕様が変わる場合があります。現状のものについて記載しています。
Cloud IoT Coreは、Cloud PubSubと違うのは、MQTT(S)機能+デバイス管理機能と考えればいいかと
まず、new device registry 作成
gcloud beta iot registries create my-registry \ --project=my-iot-project \ --region=us-central1 \ --event-pubsub-topic=projects/my-iot-project/topics/device-events
選択可能なリージョン
us-central1
europe-west1
asia-east1
証明書によるデバイス接続となる。
Azure IoTにあるようなCloud IoT自体にIP制限等の機能はない
先日AWS IoTでは、X.509証明書なしでもOAuthのようなトークン認証には現状対応していません。
公開されているサンプルをベースにポイントを記載します。サンプルは下記gitからダウンロードできます。
https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git
最初に、デバイスの証明書を発行
今回のリリースにより、Cloud IoT Coreの顧客は、自らのデバイス鍵を用意し、自身の認証局(CA)を使って署名しておくことで、Cloud IoT Coreの認証プロセスで該当鍵の署名を検証できるようになる。これによりデバイスメーカーは、自らのCAが発行した証明書を用いることで、デバイスをオフライン状態のままで一括して準備できるようになる
openssl req -x509 -newkey rsa:2048 -keyout rsa_private.pem -nodes -out \ rsa_cert.pem -subj "/CN=unused"
openssl ecparam -genkey -name prime256v1 -noout -out ec_private.pem openssl ec -in ec_private.pem -pubout -out ec_public.pem
デバイスの追加
gcloud beta iot devices create my-node-device \ --project=my-iot-project \ --region=us-central1 \ --registry=my-registry \ --public-key path=rsa_cert.pem,type=rs256
証明書の更新もgcloud beta iot devices credentials updateで行います
Cloud IoT Coreに接続するアプリを作成するには、まず以下Node.js moduleをインストールしておく
“jsonwebtoken”: “7.4.1”,
“mqtt”: “2.7.2” *
実際Cloud IoTに接続するために、利用するパッケージは、mqtt
一意のmqttClient idを付与 const mqttClientId = `projects/${argv.project_id}/locations/${argv.cloud_region}/registries/${argv.registry_id}/devices/${argv.device_id}`;
// With Google Cloud IoT Core, the username field is ignored, however it must be // non-empty. The password field is used to transmit a JWT to authorize the // device. The "mqtts" protocol causes the library to connect using SSL, which // is required for Cloud IoT Core.
const connectionArgs = { host: argv.mqtt_bridge_hostname, port: argv.mqtt_bridge_port, clientId: mqttClientId, username: 'unused', password: createJwt(argv.project_id, argv.private_key_file, argv.algorithm), protocol: 'mqtts' };
tokenをコネクションを張るごとにワンタイムパスワードを設定
// Create a JWT to authenticate this device. The device will be disconnected // after the token expires, and will have to reconnect with a new token. The // audience field should always be set to the GCP project id.
MQTTS 接続部分
// Create a client, and connect to the Google MQTT bridge. const client = mqtt.connect(connectionArgs);
client.on('connect', () => { console.log('connect', arguments); // After connecting, publish 'num_messages' messagse asynchronously, at a rate // of 1 per second for telemetry events and 1 every 2 seconds for states. publishAsync(1, argv.num_messages); });
センサーデータを見立てて、jsonデータを生成
const temperature = 20 + (Math.randam() * 15); const humidity = 60 + (Mat<span data-mce-type="bookmark" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" class="mce_SELRES_start"></span>h.random() * 20); const data = JSON.stringify({ deviceId: 'my-node-device', temperature: temperature, humidity: humidity });
// Publish "payload" to the MQTT topic. qos=1 means at least once delivery. // Cloud IoT Core also supports qos=0 for at most once delivery. console.log('Publishing message:', payload); client.publish(mqttTopic, data, { qos: 1 });
gcloud beta pubsub subscriptions pull --auto-ack projects/my-iot-project/subscriptions/my-subscription
https://cloud.google.com/pubsub/ordering?hl=ja
Cloud pubsub自体処理サーバがロードバランシングしているので、Google Cloud Pub/Sub では、高可用性と拡張性を持ったメッセージ配信サービスを使用できます。これらの機能を使用する場合の妥協点として、サブスクライバーによって受信されるメッセージの順序は保証されません。
時系列にソートさせるには、時刻のデータも一緒に送信させる仕組みは必要
projects/my-iot-project/topics/device-events をトリガーにCloud Functions、Google dataflow等に発火することができる。
/** * Triggered from a message on a Cloud Pub/Sub topic. * * @param {!Object} event The Cloud Functions event. * @param {!Function} The callback function. */ exports.subscribe = function subscribe(event, callback) { // The Cloud Pub/Sub Message object. const pubsubMessage = event.data; // We're just going to log the message to prove that // it worked. console.log(Buffer.from(pubsubMessage.data, 'base64').toString()); // Don't forget to call the callback. callback(); };
Cloud IoT Coreは、現在のところ、東京リージョン(asia-northeast1)にきていないので、IoT device間レイテンシーが気になる。
※日本から最も近いCloud IoT CoreのEdgeはasia-east1(台湾)
さらに、IoTデバイスの最新状態を取得する必要がある顧客は、最後に報告された状態やデバイスのプロパティを含む、物理デバイスの論理表現を管理できるようになる。こういったことを実現するために、デバイスがオフラインになっていても、その状態やプロパティを取得したり、アップデートしたりするためのAPIが用意されている。
gcloud beta iot devices update -blocked
https://cloud.google.com/sdk/gcloud/reference/beta/iot/devices/update
gcloud beta iot devices credentials update
https://cloud.google.com/sdk/gcloud/reference/beta/iot/devices/credentials/update