本記事はAzure Advent Calendar 2019の20日目の記事になります。
Azure IoT Hubと Functionsについて
Azure IoT HubとFunctionsを組み合わせ下り方向通信を行おうとしたところハマったので気を付けなければいけないことを記事にしました。参考になれば幸いです。
前提;IoT Hubについて
IoTを活用するために便利なAzureのPaaSとしてIoT Hubというものがあります。
https://azure.microsoft.com/ja-jp/services/iot-hub/
2019/12/20現在、「IoT デバイスと Azure 間の双方向通信を可能にするマネージド サービス」と紹介されています。
プロトコルとして以下をサポートしており、実行するためのSDKやサンプルコードがあらかじめ用意されています。
- HTTP
- MQTT
- AMQP
「双方向」ということなので、Raspberry PiなどのIoTデバイスから発生したセンサー情報を登録することができることは勿論、Azure側にて分析した結果を受信する(下り方向制御)ことができます。単体でデータの整形や処理、分析、可視化は行うことはできません。他のPaaSサービスと組み合わせることによって目的に応じたソリューションを簡単に作ることが出来ます。
前提;Functionsについて
IoT Hubと連携をするのに強力なPaaSとしてAzure Functionsというものがあります。
https://azure.microsoft.com/ja-jp/services/functions/
2019/12/20現在、「イベント ドリブン型のサーバーレス コンピューティングにとどまらない優れたプラットフォーム」と紹介されています。
通常仮想マシンを構築するとアプリケーションのインストール作業や、ファイヤーウォールなどのセキュリティの設定や運用のための監視設定などをきめ細やかに行う必要があります。しかしながらFunctionsではそのような複雑な構築や設定を行わず、プログラムを実行してくれる環境を提供してくれます。(俗にサーバーレスといいます。)
前提;Functionsにおけるバインドについて
https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-triggers-bindings
Functionsを実行するうえ設定しなければいけないのが「トリガー」と「バインド」です。
「トリガー」がきっかけ、「バインド」が他のアプリやPaaSとの接続元/接続先になります。
例えば1分おきにBlob Storageに蓄積したデータをCosmosDBへ登録したい場合、以下のように設定を行う必要があります。
- トリガー:1分おき(タイマー)
- 入力バインド:Blob Storage
- 出力バインド:CosmosDB
ちなみに以下のようにすると、HTTPのRequestに対してResponseを返す簡単なWebアプリができあがります。
- トリガー:HTTP
- 入力バインド:なし
- 出力バインド:HTTP
Functionsの出力バインドにIoT Hubを設定できない
ここまでの情報をつなぎ合わせるとFunctionsとIoT Hubを使って下り方向の制御を行いたい場合、出力バインドにIoT Hubを設定すれば、Functionsで行った処理結果をデバイスに通知できそうです。
実際以下の通り公式ドキュメントにIoT Hubを出力バインドに対応しており、設定できるサンプルコードも記載されています。
https://docs.microsoft.com/en-us/azure/azure-functions/functions-triggers-bindings#supported-bindings
https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-bindings-event-iot#output
しかしながらこの通りに実行すると、以下のようなエラーが表示されます。
Microsoft.Azure.EventHubs: Unauthorized access. 'Send' claim(s) are required to perform this operation
Functionsの出力バインドとしてIoT Hubは対応していない
入力バインドにIoT Hubを設定することはできますが、出力バインドにIoT Hubを設定できないことを以下でMicrosoftのサポートエンジニアが回答しています。
https://github.com/Azure/Azure-Functions/issues/1351
https://social.msdn.microsoft.com/Forums/en-US/a7c9f563-9d7b-4194-b66c-64da30181520/azure-function-output-binding-iot-hub?forum=AzureFunctions
本件については、MicrosoftのContributorが認めており、ドキュメントを改修する予定であることを記載しています。(2019/12/20現在修正はされていないようです。)
下り方向制御を実現するためには
「バインド」を使わず、プログラムの中でIoT HubのC2D(Cloud-to-Device通信)を呼び出すことで実現できました。
具体的には、Functionsの中でSDKをインストールし、IoTHubのデバイスIDにおけるプライマリ接続文字列をプログラムの中に埋め込んでSDK経由でIoT HubのC2Dを実行すると実現できます。
(実現するコード補足予定です…まだ間に合ってないです、すみません)