Google Cloud IoT Coreを使ってみる

# はじめに

Google Cloud [IoT Core](https://cloud.google.com/iot-core/?hl=ja)はAWSでいう[AWS IoT](https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/what-is-aws-iot.html)、MSでいう[Azure IoT Hub](https://azure.microsoft.com/ja-jp/services/iot-hub/)的な位置づけのもの。デバイスとクラウドを繋いでPub/Subできるサービスである。IoT Coreから[Cloud PubSub](https://cloud.google.com/pubsub/?hl=ja)、[Cloud Functions](https://cloud.google.com/functions/?hl=ja)と繋げてサーバレスアプリを作っていけるみたい。

現在、クローズドベータ版ということで無料で使える。申請してしばらくしたら招待がとどく。招待来てたのでつかってみた。

# つかってみる

[Quickstart](https://cloud.google.com/iot/docs/quickstart?hl=ja)にそってMQTTでPubSubしてみる。

[Cloud Platform Console](https://console.cloud.google.com/)で新規プロジェクトを作成する。

プロジェクトが作成されたら、画面左上のハンバーガーメニューから[IoT Core](https://console.cloud.google.com/iot/)を選択してIoT Coreのコンソールに移動する。

![スクリーンショット 2018-03-20 16.09.15.png](https://qiita-image-store.s3.amazonaws.com/0/61995/e6fa3bf6-0be3-9ebd-fb81-e9a63c30e30b.png)

IoT Core のAPIを有効化する。

![スクリーンショット 2018-03-20 11.02.22.png](https://qiita-image-store.s3.amazonaws.com/0/61995/2b6777d7-1aa0-1e9e-ef15-2a7f96137163.png)

Create a device registry をクリックする

![スクリーンショット 2018-03-20 16.05.18.png](https://qiita-image-store.s3.amazonaws.com/0/61995/6c96dd85-67e5-b519-3874-380e82ea5b06.png)


任意のレジストリIDを入力。今回は`btf-iot-core-test`とした。
Regionを指定。今回は `us-central1` とした。
プロトコルは、 MQTT, HTTP をチェック。
Cloud Pub/Subトピックは、新規作成して`btf-test-topic`とした。
デバイス状態のトピックは省略。

入力したら 作成 をクリック。

![スクリーンショット 2018-03-20 16.07.28.png](https://qiita-image-store.s3.amazonaws.com/0/61995/73ed52ca-47d7-6a43-1b39-7b1ac7bbe6d9.png)


端末を追加 をクリック。

![スクリーンショット 2018-03-20 16.14.11.png](https://qiita-image-store.s3.amazonaws.com/0/61995/ebda3599-3880-ce24-c86e-9c7d61e5b79b.png)


ターミナルを開いて、以下のコマンドで公開鍵を作成する。

```
openssl req -x509 -newkey rsa:2048 -keyout rsa_private.pem -nodes  -out rsa_cert.pem -subj "/CN=unused"
```

端末を追加 の画面で以下を入力する。

端末ID: 任意のID。今回は `btf-iot-device-test`とした。
端末の通信: 許可
認証: 手動で入力
公開鍵の形式: RS256_X509
公開鍵の値: 先ほど生成した `rsa_cert.pem` の中身
公開鍵の有効期限: 省略
端末メタデータ: 省略

入力したら 追加 をクリックする

![スクリーンショット 2018-03-20 16.26.12.png](https://qiita-image-store.s3.amazonaws.com/0/61995/7a01f32f-f879-9ebd-7973-98cde382a2df.png)


端末に以下のサンプルコードのリポジトリをcloneして、`./nodejs-docs-samples/iot/mqtt_example` に移動する

```
git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples
cd ./nodejs-docs-samples/iot/mqtt_example/
```

先ほど生成した秘密鍵を同ディレクトリにコピーする

```
cp ../../../rsa_private.pem ./
```

依存モジュールをインストールする

```
npm install
```

トピックをサブスクライブする。`[PROJECT_ID]`はプロジェクトのID、`btf-test-subscription`の部分は任意のサブスクリプション名を指定、`btf-test-topic`の部分はレジストリ作成の時に作成したトピック名。ここでは `btf-test-topic` となる。

```
gcloud pubsub subscriptions create \
    projects/[PROJECT_ID]/subscriptions/btf-test-subscription \
    --topic=projects/[PROJECT_ID]/topics/btf-test-topic
```

サンプルコードを実行する。`[PROJECT_ID]`はプロジェクトのID、`btf-iot-core-test`はレジストリ作成のときに指定した任意のレジストリID、`btf-iot-device-test`は端末作成の時に指定した任意のデバイスID。

```
node cloudiot_mqtt_example_nodejs.js \
    --projectId=[PROJECT_ID] \
    --registryId=btf-iot-core-test \
    --deviceId=btf-iot-device-test \
    --privateKeyFile=rsa_private.pem \
    --numMessages=25 \
    --algorithm=RS256
```

実行すると、MQTTでデータがパブリッシュされていく。

![スクリーンショット 2018-03-20 16.46.04.png](https://qiita-image-store.s3.amazonaws.com/0/61995/0345fb20-9fef-8af7-fd8f-88a3a0cfe71d.png)

ターミナルで別タブを開いて、サブスクライブされているメッセージを確認する。`[PROJECT_ID]`はプロジェクトのID。`btf-test-subscription`はサブスクリプション作成のときに指定したサブスクリプション名

```
gcloud pubsub subscriptions pull --auto-ack \
    projects/[PROJECT_ID]/subscriptions/btf-test-subscription
```

以下のように、パブリッシュされたメッセージが確認できた

```
$ gcloud pubsub subscriptions pull --auto-ack     projects/[PROJECT_ID]/subscriptions/btf-test-subscription
┌──────────────────────────────────────────────────┬────────────────┬────────────────────────────────────┐
│                       DATA                       │   MESSAGE_ID   │             ATTRIBUTES             │
├──────────────────────────────────────────────────┼────────────────┼────────────────────────────────────┤
│ btf-iot-core-test/btf-iot-device-test-payload-14 │ 58564552499088 │ deviceId=btf-iot-device-test       │
│                                                  │                │ deviceNumId=2750966584450049       │
│                                                  │                │ deviceRegistryId=btf-iot-core-test │
│                                                  │                │ deviceRegistryLocation=us-central1 │
│                                                  │                │ projectId=[PROJECT_ID]      │
│                                                  │                │ subFolder=                         │
└──────────────────────────────────────────────────┴────────────────┴────────────────────────────────────┘
```

# IoT Core関係を削除する

いままで設定したサブスクリプション、レジストリ、端末をひとつひとつ消していく必要があってけっこうめんどい。

[Cloud PubSubのコンソール](https://console.cloud.google.com/cloudpubsub/)に移動してトピック名を選択してオプションメニューから削除を選択する

![スクリーンショット 2018-03-20 16.56.31.png](https://qiita-image-store.s3.amazonaws.com/0/61995/792b100a-6546-f456-4ec0-82c9ea87d17c.png)


[IoT Core 端末レジストリ](https://console.cloud.google.com/iot/registries)に移動してレジストリIDをクリック

![スクリーンショット 2018-03-20 16.59.34.png](https://qiita-image-store.s3.amazonaws.com/0/61995/eab0b585-cc5a-c07f-4ebe-2868dab220e5.png)


画面下部の端末IDをクリック

![スクリーンショット 2018-03-20 17.00.25.png](https://qiita-image-store.s3.amazonaws.com/0/61995/93af06b5-9fe5-dc8b-b132-bf7bb19e8076.png)


端末の詳細 で削除をクリック。

![スクリーンショット 2018-03-20 17.01.24.png](https://qiita-image-store.s3.amazonaws.com/0/61995/0f1f81a5-dbdd-f634-c920-785ee6698c0b.png)


端末名を入力して 削除 をクリック。端末が複数登録されている場合は全ての端末を削除する必要がある。

![スクリーンショット 2018-03-20 17.02.51.png](https://qiita-image-store.s3.amazonaws.com/0/61995/7ee1f59a-7445-21df-5513-b753f56bd3d8.png)


レジストリに登録されている端末が全て削除されると、レジストリの削除ボタンが有効になる。削除をクリックする

![スクリーンショット 2018-03-20 17.03.57.png](https://qiita-image-store.s3.amazonaws.com/0/61995/92cff23a-991a-b70e-f98c-957f040f45f4.png)


レジストリ名を入力して 削除 をクリックする

![スクリーンショット 2018-03-20 17.05.10.png](https://qiita-image-store.s3.amazonaws.com/0/61995/4fe28069-ba0c-8641-51f6-f012002dcdf0.png)


# まとめ

ざっくりとした所感では、AWS IoTやAzure IoT Hubと特に変わらない感じ。ただIoT Coreはより純粋にBrokerの役割でCloud PubSubでサブスクライブするってことを意識しておく必要があるかな。じゃないと管理画面で迷うこともあるかも。って思いました。

あと、Firebaseで作成したプロジェクトからIoT CoreのAPIの有効化をしようとすると成功しなかった。GCPコンソールではFirebaseのプロジェクトとその他のプロジェクトが混在するのでこのへんなんとかしてほしい。IoT Coreに限った話じゃないけど。

あとでPubSubをトリガにしたCloud Functionsなんかもやってみたいと思います。