LoginSignup
4
5

More than 3 years have passed since last update.

GCPのほうのIoTCoreを使ってみる

Last updated at Posted at 2020-03-22

はじめに

こんにちは
RHEMS技研荒木です。
無人島に漂流しすぎて寝不足です。島の名前はI/O島にしました。

備忘録がてらIoTCoreを用いたセンサデータの収集についてまとめました。
2020/03/21現在の情報です。1~2ヶ月のうちに情報が古くなると思いますのでご注意ください。

構成図

ReikouzoPNG (1).png

センサデータを収集するためのスタンダードな構成だと思います。
CloudFunctionはデータ到達確認のため置いています。 ここでは解説しません。

IoTCore

これはAWSでいうIoTCoreと似たサービスになります。そりゃそうなんですけど。
大きく違う点はレジストリ単位でトピックが決まっている等点になります。AWSではエンドポイントは固定でトピックはデバイスごとに選択できるのですが、GCPではレジストリに属しているデバイスはすべて同じトピックへの送信になります。

設定をしていきます。
まずプロジェクトを作成します。
今回はqiita-akijin-testという名前にしました。
スクリーンショット 2020-03-21 14.16.21.png

組織や場所は環境によります。
問題なければ作成してしまいます。

次はIoTCoreを有効にします。
左のナビゲーションメニューよりIoTCoreを探します。
初回では画像のような画面になるので有効にするを選択してAPIを有効にします。
スクリーンショット 2020-03-21 14.17.10.png

有効になると下画像の用になりますので上のレジストリを作成を選択。
スクリーンショット 2020-03-21 14.18.14.png

すると、レジストリの設定が出るので設定をしていきます。
今回は画像の通りの設定をしました。
MQTTでしか通信する予定がないのでHTTPのチェックは外しておきましょう。
スクリーンショット 2020-03-21 14.19.12.png
スクリーンショット 2020-03-21 14.19.35.png

次にデバイスの登録をするのですが先に証明書関係をクリアしておきましょう。

$ openssl ecparam -genkey -name prime256v1 -noout -out ec_private.pem
$ openssl ec -in ec_private.pem -pubout -out ec_public.pem
$ openssl ec -in ec_private.pem -noout -text

上2つのコマンドでサーバー側とデバイス側の証明書を作成、3つ目でデバイスに書き込む用の証明書を書き出しています。
書き出すと画像のように出るのでprivの方を後ほど使うのでコピーしておきます。
また、先頭が00だった場合は00を抜かしてコピーします。
スクリーンショット 2020-03-21 14.28.43.png

ではデバイスの登録をしていきます。
左のメニューよりデバイスを選択してデバイスを作成を選択します。
スクリーンショット 2020-03-21 14.55.58.png

デバイスの設定は画像の通りです。
証明書は公開鍵の形式ES256にしてec_public.pemの中身をペーストします。
各種設定が終わったら作成してしまいましょう。
スクリーンショット 2020-03-21 14.56.30.png
スクリーンショット 2020-03-21 14.56.45.png

スクリーンショット 2020-03-21 15.06.17.png

これでIoTCoreの設定は終了になります。

Pub/Sub

これはIoTCoreに届いたリクエストを他のGCPのサービスに割り振るために使用します。基本的にIoTCoreを使用する際はPub/Subは必ず使用します。
ここでの設定は特にないです。
IoTCoreのレジストリからPub/Subのページに飛びます。先程作成したトピックで作られているかを確認します。
スクリーンショット 2020-03-21 15.24.06.png

BigQuery

先にBigQueryのテーブルを作成します。
左メニューよりBigQueryを選択。プロフェクト名がリソースに追加されているので選択して右側にあるデータセットを作成を選択します。
スクリーンショット 2020-03-21 15.42.19.png
スクリーンショット 2020-03-21 15.42.42.png

作成したらテーブルを作成します。今回は画像のように設定しました。
スクリーンショット 2020-03-21 15.43.57.png

作成するとリソースに画像のようなツリーができていることを確認します。
スクリーンショット 2020-03-21 15.44.14.png
テーブルが作成されていることも確認しましょう。
スクリーンショット 2020-03-21 15.44.24.png

これでBigQueryの設定は終わりです。

Dataflow

これはサービスとサービスとの間に入れるものになります。テンプレートが予め用意されているので簡単に使用することができます。
使用するテンプレートはPub/Subの指定したトピックに届いたデータをBigQueryに追加してくれるものになります。
今回では、test-akijinに届いたメッセージをBigQueryへと送ります。

Storage

AWSで言うところのS3がこれに当たります。
Dataflowはデータを処理するのにバッファリングをします。なのでバッファを作成する必要があり、Storageにバッファを作成するようになっています。
左のメニューよりStorage-ブラウザを選択。
バケットの作成よりバケットを作成していきます。設定は画像のとおりです。
スクリーンショット 2020-03-21 15.36.13.png
バケット内にフォルダを一つ作成しておきます。このフォルダがDataflowで使用するバッファになります。
これでバッファは用意されました。

Dataflowの設定に戻ります。
Pub/SubのメニューよりBIBQUERYにエクスポートを選択。
スクリーンショット 2020-03-21 15.53.03.png

するとDataflowの設定に飛ぶので画像のように設定します。
リージョンエンドポイントはDataflowの元であるComputeEngineが置かれるリージョンを指定します。なるべく近いリージョンを選ばないと他のサービスとの地理的距離が大きくなってしまうので料金がかさむ要因になります。
BigQuery output tableでは書き込むBigQuery先を選択します。<プロジェクト名>:<データセット名>.<テーブル名>の形式で入力するので、qiita-test-akijin:test.secret_wordとなります。
一時的なロケーションには先程作成したStorageのバッファの場所を入力します。
スクリーンショット 2020-03-21 16.45.53.png

設定し終えたらDataflowの設定は終わりです。
GCP側での設定も終了です。

デバイスの設定

デバイスはESP32を使い、ArduinoIDEで進めていきます。他のエディタでも同様に進めることができると思います。
IoTCoreでの設定の通り、通信にはHTTPではなくMQTTで通信をしていきます。
通信用のコード・ライブラリも用意されているものを使用します。
https://github.com/GoogleCloudPlatform/google-cloud-iot-arduino
をクローンして通常のライブラリを入れる要領で追加します。

使いしたらサンプル例より、Esp32-lwmqttを開きます。
開くとinoファイルとヘッダーファイルが2つが開かれます。
ciotc_config.hがWiFiやGCP,MQTTの設定用ファイルになりますので編集していきます。
17行目以下のところを編集します。

// Wifi network details.
const char *ssid = "SSID";
const char *password = "PASSWORD";

// Cloud iot details.
const char *project_id = "qiita-test-akijin";
const char *location = "asia-east1";
const char *registry_id = "akijin-test";
const char *device_id = "test1";

WiFiの設定は飛ばします。
GCPの設定は変数名を参考にして書き換えます。

42行目以下は証明書を貼り付けていきます。

// is probably wrong with your key.
const char *private_key_str =
    "22:d7:a2:63:05:b0:3d:df:53:71:e5:bc:53:cf:0a:"
    "81:00:88:f3:4f:48:4e:82:3b:37:c6:e7:86:e9:02:"
    "fa:e0";

esp32-mqtt.hの中身も少し書きえます。
setupWifiが名前の通りWiFiの設定なのですが、中身を以下のように書き換えます。
書き換えることによってライブラリのインクルードが必要になるので追加・継承までします。

#include <Client.h>
#include <WiFiManager.h>
#include <WiFiClientSecure.h>

WiFiClientSecure client;
WiFiManager wifiManager;
void setupWifi() {
  Serial.println("Starting wifi");

  Serial.println(wifiManager.autoConnect());

  IPAddress ipadr = WiFi.localIP();
  Serial.println(ipadr);
  Serial.println(WiFi.SSID());

  configTime(0, 0, ntp_primary, ntp_secondary);
  Serial.println("Waiting on time sync...");
  while (time(nullptr) < 1510644967) {
    delay(10);
  }
}

こうすることによってWiFiの設定を書き込まずともPCやスマホで設定ができるようになりました。詳細は僕の他の記事やautoconnectについて検索してください。

最後にEsp32-lwmqtt.inoを編集してきます。
loopを以下のように変更します。

void loop() {
  mqtt->loop();
  delay(10);  // <- fixes some issues with WiFi stability

  if (!mqttClient->connected()) {
    connect();
  }

  publishTelemetry("{\"Hello\":\"World\"}");
  delay(10000);
}

publishTelemetry();の引数が送信するデータになります。
BigQueryは追加するデータをJsonで指定するので"{\"Hello\":\"World\"}"を引数にします。
10秒に一回送信され、BigQueryのDataflowで設定したテーブルのHelloの列に文字列のWorldが追加されます。
Dataflowの方でバッファリングするので10秒に一回追加されるわけではないので注意が必要です。

BigQueryに戻り、プレビューで追加されていることを確認します。
スクリーンショット 2020-03-21 16.50.22.png
無事に追加されているはずです。
これでセンサデータの収集は終わりです。

料金

これが一番気になるところです。AWSと比較してみます。
AWSはIoTCoreとDynamoDBを使用したとして比較します。
台数は1台で1時間に12回(5分おき)の送信で1ヶ月での運用と仮定して考えます。
また15分おきにPingを送ります。
メッセージ数12*24*31= 8640が一ヶ月のメッセージ数になります。
一ヶ月は44640分です。
リージョンはいずれも東京です。

AWS

まずAWSです。

IoTCore

https://aws.amazon.com/jp/iot-core/pricing/?nc=sn&loc=4ここを参考にします。

0.096/1000000*44640 = 0.0042...が接続しているための料金

1.20/1000000*86400 = 0.10368 がメッセージ送信のための料金

0.18/1000000*86400*2 = 0.031...がルールの料金(DynamoDBへのインサート)

合計して0.01388USDがIoTCoreの一ヶ月あたりの料金です。

DynamoDB

https://aws.amazon.com/jp/dynamodb/pricing/on-demand/より、書き込みだけを想定します。
100 万単位あたり 1.4269USDなので、1.4269/1000000*8640 = 0.0123...がDynamoDBの料金になります。

各サービスの合計で0.1511USDが一ヶ月あたりの料金になります。

GCP

IoTCore

https://cloud.google.com/iot/pricing?hl=ja#overviewの例から計算します。
4*24*30*1024 =294.9120kB
250MBまで無料なのでIoTCoreでは料金はかからないみたいです。

Pub/Sub

送受信するデータが10GBに満たないので無料になります。

Dataflow

DataflowではCompute Engineという他のサービスで料金計算になります。
ここのサイトを参考にします。
今回はストリーミング処理なので1時間あたり約0.35\$かかります。したがって、0.35*24*31=260.6$となります。
これが一番やばい。
これはテンプレートを使用した際ストリーミング処理になってしまうので1台で運用する際はバッチ処理が適切だと思います。
そうした際はテンプレートを使用しないのでJavaもしくはPythonでコードを書くことになります。

BigQuery

料金計算が複雑なため公式のサイトを御覧ください。
https://cloud.google.com/bigquery/pricing?hl=ja#on_demand_pricing

合計で260.6~USDになります。
Dataflowが主に占めています。台数が少ないならCloudFunctionとかで代用したほうがかなりコストが削減できそう。

さいごに

プログラムもほぼ書かないでデータの収集までできました。
このぐらいなら初学者の方でも簡単にできそうなのでお試しください。

追記(2020/03/27)
コストカットができたので続編でまとめています。
https://qiita.com/Akijin/items/8ce14a6b1d4ffe468a74

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5