Google Cloud IoT CoreをMQTTとNode.jsで試してみる

## Google Cloud IoT Core?

<img width="928" alt="iotintro.png" src="https://qiita-image-store.s3.amazonaws.com/0/76873/dcf8e484-bdd1-a81c-925c-c71f3649f6e8.png">

CloudIotCoreの提供する機能は割とシンプルで

* ProtocolBridige (MQTT To HTTP)
* DeviceManagement

の二つ。
サービス側からクライアントにブロードキャストで設定変更を伝える、とか
クライアント側からMQTTを利用したいが、Cloud Pub/SubはHTTPしかサポートしていないので、そういう場合のブリッジ的な使い方であったりみたいなユースケースを想定している。
MQTTのブローカーとしての役割ももちろんこなすので、自前でRabbitMQとかブローカーさんを立てて、お世話しなくて済む。

CloudIotCoreから先はCloud Pub/Subでお好きなように、という感じかなと。

AWS IoTでも似たような事はできると思うのですが、BigQueryやCloud Pub/SubのようなGCP内での連携用途ならGCP完結できないかなーって欲望の場合はこちらのが良さげな気がしたので触ってみました。

ちなみにβ(2018年1月現在)。

## 前準備

CLIを使うため、[GCPのSDK](https://cloud.google.com/sdk/?hl=ja)のインストールが必要です。

* install

```
# SDK install
$ curl https://sdk.cloud.google.com | bash
#ブラウザで認証する場合は以下、しない場合はGCPコンソールから秘密鍵のダウンロードと設定が必要
$ gcloud auth application-default login
# beta componentをinstall
$ gcloud components install beta
```

## GCPで端末レジストリを作成

<img width="519" alt="iotcore.png" src="https://qiita-image-store.s3.amazonaws.com/0/76873/9ff2c34e-5f44-25c5-0538-4e81f3468ea3.png">


テレメトリとデバイス状態については別途Cloud Pub/Subからトピックを作成します。

## クライアント設定と試行

[公式のサンプル](https://github.com/GoogleCloudPlatform/nodejs-docs-samples#setup)と[QuickStart](https://cloud.google.com/iot/docs/quickstart)を見ながら。

とりあえず気楽にPCからjsでテストできるようにしてみる。

### クライアントサンプルをclone

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

### 依存パッケージのinstall

```
cd nodejs-docs-samples/iot/mqtt_example/
npm install
```

### 公開鍵と秘密鍵をOpenSSLで作成する

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

### コンソール上から先ほど作成したデバイスレジストリに端末を登録

端末IDは任意。
公開鍵はRSA256-X509を選択して、先ほど作成した公開鍵をはっつけてあげてください。

<img width="488" alt="iot-client2.png" src="https://qiita-image-store.s3.amazonaws.com/0/76873/abdbd84e-e54e-0119-d316-f9864a21898c.png">




### レジストリ作成時に指定したトピックのサブスクライブ

```
gcloud beta pubsub subscriptions create \
    projects/PROJECT_ID/subscriptions/your-subscription-name \
    --topic=projects/PROJECT_ID/topics/your-telemetry-topic
```

* PROJECT_IDは自分のプロジェクトに置き換えてください。
* subscription名はお好みで、先ほどデバイスレジストリに設定したtopicを参照するように。

### トピックにメッセージをパブリッシュする

```
node cloudiot_mqtt_example_nodejs.js \
    --projectId=my-proj \
    --registryId=my-device-registry \
    --deviceId=my-test-device \
    --numMessages=10 \
    --privateKeyFile=rsa_private.pem \
    --algorithm=RS256 \
    --cloudRegion=asia-east1
```

* projectIdは自分のプロジェクトに置き換える
* registryId,deviceIdは先に登録した物に置き換え。

### メッセージが届いているか確認する

```
gcloud beta pubsub subscriptions pull --auto-ack \
    projects/PROJECT_ID/subscriptions/your-telemetry-topic

┌──────────────────────────────────────────────┬────────────────┬───────────────────────────────────┐
│                     DATA                     │   MESSAGE_ID   │             ATTRIBUTES            │
├──────────────────────────────────────────────┼────────────────┼───────────────────────────────────┤
│ xxxxxxxxxxxxx/xxxxxxxxxxxxx-device-payload-3 │ 22232850207119 │ deviceId=xxxxxxxxxxxxxxxxxxxx     │
│                                              │                │ deviceNumId=3155016929003157      │
│                                              │                │ deviceRegistryId=xxxxxxxx-test    │
│                                              │                │ deviceRegistryLocation=asia-east1 │
│                                              │                │ projectId=xxxxxxxxx               │
│                                              │                │ subFolder=                        │
└──────────────────────────────────────────────┴────────────────┴───────────────────────────────────┘
```