Sigfox CallbackとGoogle Cloud Platform連携

技術情報

先日開催されたGoogle I/O 2019でGoogle Cloud PlatformとSigfox IoT Networkとの連携がGCPコミュニティから公開されました。この連携を用いることで、SigfoxデバイスからCallbackされるデータをCloud Pub/Subを経由し、GCPサービスで活用することが可能になります。
※元情報はこちら動画チュートリアルを見てください。

img-190513-01-technical-01.png

事前準備

事前に、Google Cloud PlatformのアカウントとSigfoxバックエンドのアカウントを取得してください。Sigfoxバックエンドクラウドのアカウントをお持ちでない方は、Sigfox Shield for ArduinoSigfox Breakout Boardをご購入いただき、Sigfox Buyからアカウントを取得してください。

Google Cloud Platformプロジェクトの作成

下記手順でGCPプロジェクトを作成してください

1.GCPコンソールに移動
2.画面左上のプロジェクト選択後、【新しいプロジェクト】を選択
3.プロジェクト名を入力し【作成】ボタンをクリック(今回は”Sigfox-GCT"というプロジェクト名で説明します)

img-190513-01-technical-02.png

4.再度、プロジェクト選択をクリックし、先ほど作成した新規プロジェクトを選択img-190513-01-technical-03.png

5.左ナビゲーションメニューから"APIとサービス" > "ライブラリ"を開く
6.下記APIが有効になっているかを確認し、もし有効になっていない場合は有効にしてください

    • Cloud Functions API
    • Cloud Pub/Sub API
    • Cloud Datastore API

Sigfox Callback用Cloud Functionsをデプロイ

1.ローカル開発環境にGoogle Cloud SDK (gcloudコマンドラインツール)、git、python、pip、virtualenv、curlをインストールしてください。

2.先程作成したGCPプロジェクトの初期設定を下記コマンドで行います
$ gcloud init

3.Sigfoxデバイスのデータを受け取るPub/Sub topicを作成
$ gcloud pubsub topics create sigfox-data

4.必要に応じ、上記topicのメッセージをモニタリングするためのPub/Subサブスクリプションを作成します
$ gcloud pubsub subscriptions create sigfox-data-sub --topic sigfox-data

5.GCPコミュニティが公開しているGitHubリポジトリをCloneします
$ git clone https://github.com/GoogleCloudPlatform/community.git

6.sigfox-gwディレクトリに移動します
$ cd community/tutorials/sigfox-gw

7.新たにPythonの仮想環境を作成します
$ virtualenv venv

8.作成した仮想環境のbin/activateに対して、sourceコマンドを使用することにより、Pythone仮想環境を起動します
$ source venv/bin/activate

9.必要なPythonモジュール群をインストールします。
(venv) $ pip install -r requirements.txt

10. cf ディレクトリに移動
(venv) $ cd cf

11.Cloud Functionsは、cfディレクトリ(sigfox-gw/cf)に".env.yaml"という設定ファイルがあります。この設定ファイルは、Cloud Functionsがデプロイされた時に読み込まれますので、もし、設定ファイルを更新した場合は、(後述のデプロイ方法で)再度デプロイする必要があります。

12. .env.yaml ファイルを編集します。
(venv) $ vi .env.yaml

env.yaml
PUBSUB_TOPIC_DATA: sigfox-data
HTTP_USER: ********
HTTP_PASSWD: ********
DATASTORE_KIND: deviceType
DATASTORE_PROPERTY: config

.env.yamlファイルの HTTP_USER HTTP_PASSWORD をご自由に設定してください。これらの項目は、SigfoxバックエンドクラウドからGCPにCallbackする際のCloud FunctionsがHTTPS通信時に、Sigfoxバックエンドを認証するために使用するBasic認証情報となります。
後ほど、設定に使いますので、HTTP_USERとHTTP_PASSWORDをメモしておいてください。

13.下記コマンドを使用し、2つのCloud Functionsをデプロイします。(--region値は、ご自身がデータの蓄積・処理を希望するCloud Functionsリージョンを設定してください。)
Sigfox Dataコールバック用
(venv) $ gcloud beta functions deploy --region asia-northeast1 --runtime python37 --env-vars-file .env.yaml --trigger-http callback_data
Sigfox Serviceコールバック用
(venv) $ gcloud beta functions deploy --region asia-northeast1 --runtime python37 --env-vars-file .env.yaml --trigger-http callback_service

callback_dataは、Sigfoxデバイスのメッセージペイロードを受け取るためのものであり、Sigfoxバックエンドの UPLINKや BIDIR、DATA_ADVANCEDコールバックに対応します。
callback_serviceは、Sigfoxネットワークのイベント情報、エラー情報などを受け取るためのものであり、SigfoxバックエンドのSTATUSやACKNOWLEDGE、ERRORコールバックに対応します。

このコマンドを実行すると、下記例のようなHTTPS Trigger URLがコマンド出力されます。

httpsTrigger:
  url: https://asia-northeast1-sigfox-gcp.cloudfunctions.net/callback_data

このURLはCloud FunctionsのリージョンやGCPプロジェクト名に応じ、下記フォーマットで出力されます。
https://[リージョン]-[プロジェクト名].cloudfunctions.net/callback_data
https://[リージョン]-[プロジェクト名].cloudfunctions.net/callback_service
※この2つのURLは後ほど使いますので、メモしておいてください。

14.デプロイが終了すれば、Cloud FunctionsのWebコンソールで、2つのCloud Functionsがデプロイされていることを確認することができます。

img-190513-01-technical-04.png

Sigfox Callbackを作成

Sigfox Cloud API V2を使用することにより、Sigfox Callbackを自動作成することができます。

Sigfox Cloud APIを有効にする

こちら(Sigfox Backend Cloud APIの利用方法)を参考にSigfox API Credentialを作成し、API user's LoginAPI user's Passwordをメモしてください。

Sigfox Callbackを設定する

Sigfox API V2 Python clientを導入する

Paython clientライブラリを使用することにより、Sigfox Callbackを簡単に設定することができます。

1.もし、お使いの開発環境がcfディレクトリにいる場合は、メインディレクトリ(sigfox-gwディレクトリ)に移動します
(venv) $ cd ..

2.Sigfox API V2定義からPython client libraryを生成します。
curl -X POST -H "content-type:application/json" -d '{"swaggerUrl":"https://support.sigfox.com/api/apidocs"}' https://generator.swagger.io/api/gen/clients/python

3.上記コマンドを叩くと、生成されたPython client libraryをダウンロードするURLがコマンド出力されます。出力されたcodeをコピーし、下記コマンドを入力してください
(venv) $ curl -o python_client.zip https://generator.swagger.io/api/gen/download/[YOUR_UNIQUE_STRING]
[YOUR_UNIQUE_STRING]のところに先ほどコピーしたcodeを入力してください。

出力されるcodeは下記のようなランダム文字列コードです(一部?で置き換えています)
{"code":"6559a581-c317-4e8a-bd34-????????????","link":"https://generator.swagger.io/api/gen/download/6559a581-c317-4e8a-bd34-????????????"}

4.ダウンロードしたpython_client.zipを解凍します。
(venv) $ unzip python_client.zip

5.swagger_clientフォルダを作業ディレクトリにコピーします。
(venv) $ cp -r python-client/swagger_client .

Callback設定スクリプトを編集する

sigfox-api.iniファイルを編集し、Sigfox Callbackの自動設定に必要な情報を入力します。

sigfox-api.ini
[default]
host = https://api.sigfox.com/v2
callbacks = sigfox-api-callbacks.json
# Configure the below parameters with your values api_username = [Sigfox APIのLoginユーザ]
api_password = [Sigfox APIのLogin Password]
id = [GCPと連携するデバイスタイプのDeviceType ID]
cf_data = [Cloud Function Trigger URL*]
cf_service = [Cloud Function Trigger URL*]
cf_username = [sigfox-gw/cf/.env.yamlに記載されているHTTP_USER]
cf_password = [sigfox-gw/cf/.env.yamlに記載されているHTTP_PASSWORD]

Cloud Function Trigger URLは上述の設定で異なりますが、サンプルとしては下記のようなURLとなります。
cf_data = https://asia-northeast1-sigfox-gct.cloudfunctions.net/callback_data
cf_service = https://asia-northeast1-sigfox-gct.cloudfunctions.net/callback_service

Sigfox Callbackを一覧表示する

sigfox-api.pyにより、既に設定済みのSigfox Callbackリストを表示することができます。

1.sigfox-apiのヘルプから利用可能なオプションを確認します。
(venv) $ python sigfox-api.py -h

ただ、私の環境では、sigfox-api.pyを実行した時に2か所のSyntaxErrorが発生しました。
対象ファイル

swagger_client/models/bulk_device_asynchronous_request.py

swagger_client/models/asynchronous_device_creation_job.py

いずれのファイルもdevice_type_id='The device's name prefix'の"device's"を"devices"にしました。

2.下記コマンドを実行し、自身のデバイスタイプに設定されているCallback一覧を表示します。
(venv) $ python sigfox-api.py --callbacks list

Callbackが一つもない場合は、下記の結果となります
0 Callbacks configured for Device Type: {デバイスタイプ名}

Sigfox Callbackを作成する

1.下記コマンドにより、GCPとの連携で使用する5種類のCallbackが生成されます。
(venv) $ python sigfox-api.py --callbacks create
Callback作成に成功すると下記ようなコマンド出力となります。

Creating 5 callbacks.
Done creating 5 Callbacks for Device Type:
Enabling Downlink for BIDIR Callback
Downlink enabled.

私の環境では、sigfox-api.pyの202行目あたりの下記コードで

(抜粋)sigfox-api.py
callback = swagger_client.CallbackCreation(......)

CallbackCreationなんてないよというエラーが出てきました。

応急処置のため、下記コードのように、連想配列をそのまま書いて通しました。

(追加)sigfox-api.py
  callback = {
      'channel': d['channel'].encode('utf-8'),
      'callbackType': d['callbackType'],
      'callbackSubtype': subtype_value,
      'enabled': d['enabled'],
      'sendDuplicate': d['sendDuplicate'],
      'dead': d['dead'],
      'url': url,
      'httpMethod': d['httpMethod'].encode('utf-8'),
      'headers': headers,
      'sendSni': d['sendSni'],
      'bodyTemplate': d['bodyTemplate'].encode('utf-8'),
      'contentType': d['contentType'].encode('utf-8')
  }

2.念のためCallbackを確認します
(venv) $ python sigfox-api.py --callbacks list

3.(option)もし、Sigfox API CredentialやDeviceType ID、GCPのBasic認証情報を間違ってしまった場合は、下記コマンドで全てのCallbackが削除されますので、
(venv) $ python sigfox-api.py --callbacks delete-all
削除後、sigfox-api.iniファイルを修正後、python sigfox-api.py --callbacks createコマンドで再度Callbackを作成してください

作成したSigfox Callbackを確認する

SigfoxバックエンドのDEVICE TYPE [ご自身のデバイスタイプ] > CALLBACKSメニューに移行すると下図のように5種類のCallbackが作成されていることを確認できます。
img-190513-01-technical-05.png

デバイス制御管理用Datastoreを作成

Cloud Datastore database serviceを利用して、Sigfox下りメッセージを定義し、デバイス制御管理を行うことが可能です。
ただし、この方法は、該当のデバイスタイプに属する全てのデバイスに対して同一のものになることにご留意ください。

1.Google Cloud Datastoreコンソールに移動
img-190513-01-technical-06.png

2.DATASTOREモードを選択し、GCPのリージョンに近いロケーション(今回はasia-northeast1(Tokyo))を選択し、【データベースを作成】します。
img-190513-01-technical-07.png

3."エンティティを作成"をクリックし、下記画面において
img-190513-01-technical-08.png
下記の通り、設定し【作成】ボタンをクリックします。

項目設定値
種類 deviceType
キー識別子 カスタム名
カスタム名 <ご自身のデバイスタイプ名>
プロパティ
名前 config
タイプ 文字列
16文字(0~9,a~f)

動作確認

これで、Google Cloud FunctionsとSigfoxバックエンドの連携ができました。実際にSigfoxデバイスからメッセージを送信し、動作確認をしましょう。

Sigfoxデバイスからメッセージを送信し確認する

次の手順で、callback_dataクラウド関数を確認します。
1.開発環境のコンソールで、Cloud Functionsが使用するPub/Subトピックに加入したCloud Pub/Subサブスクリプションがあることを確認します。次のコマンドを実行してください。
gcloud pubsub subscriptions list
下記のようなコマンド出力を確認できます。

...
name: projects/[YOUR-PROJECT]/subscriptions/sigfox-data-sub
...
topic: projects/[YOUR-PROJECT]/topics/sigfox-data

2.SigfoxバックエンドとGoogle Cloud Functions Webコンソールを開きます

3.Sigfoxデバイスからメッセージを送信します

4.SigfoxバックエンドのDEVICE > MESSAGESビューで送信されたメッセージとともにCallbackが成功していることを示すimg-190513-01-technical-09.pngマークが表示されていることが確認できます。

5.メッセージペイロードがPub/Sub topicに転送されていることを確認するため下記コマンドを実行します。
(venv) $ gcloud pubsub subscriptions pull sigfox-data-sub --limit 100 --auto-ack
このコマンドの結果、Pub/Sub topicに転送されていることを下記例のように確認できます。

{"deviceType": "", "device": "", "time": "1557499555",
"data": "000102030405060708090a0b", "seqNumber": "1234", "ack": "false"}

6.さらにcallback_dataCloud Functionを選択し、"ログを表示"をクリックすることにより、
img-190513-01-technical-10.png
下図のようにStackdriver LoggingからReceived Sigfox messageを確認することができます。
img-190513-01-technical-11.png

GCPコミュニティのチュートリアルでは、更にDATA ADVANCED Callbackや下りメッセージ処理などの例も説明されていますので、是非見てください。