IoTHubデバイス開発を極める - IoT Hub Device SDKのラインナップ

Build 2022で、Azure IoTデバイスを開発するSDKの第二世代(Generation 2)を出したよとアナウンスがありました(関連記事)。 これに合わせて、マイクロソフトの公式ドキュメントもいくつか変更されています。 そこで、これから何回かに分けて最新の事情を踏まえてAzure IoT Hubに接続するデバイス開発の考え方や方法を書いてみようと思います。モチベーションの続く限り。。。

今回はAzure IoT Hub Device SDKのラインナップを紹介します。

バイスエンドポイント

SDKの話に入る前に、デバイスとAzure IoT Hubがどうやって通信するのかについて理解しておきましょう。

外部からAzure IoT Hubに接続、通信する口を、Azure IoT Hubではエンドポイントといいます。デバイスとAzure IoT Hubの間の通信に使うエンドポイントはバイスエンドポイントというもので、Azure IoT Hubを作成すると勝手に用意されています(ビルトインエンドポイントという扱い)。

MQTT Brokerと違い、API?がデバイス用とバックエンド用で明確に分かれています。

では、デバイスからデバイスエンドポイントにどうやって通信するのか?というと、MQTTAMQPHTTPSMQTT over WebSocketAMQP over WebSocketで接続、通信することができます。 同一TLS接続に1つのデバイス情報だけを流すときはMQTT、同一TLS接続に複数のデバイス情報を流すときはAMQP、MQTTもAMQPも使えないときはHTTPSを使います。まぁ、普通のデバイスはMQTTで、Azure IoT EdgeのようなゲートウェイのときはAMQPを使うという理解で良いでしょう。ファイアウォールがMQTTやAMQPをを通さないときは、over WebSocketで回避することができます。通信プロトコルによって出来ること、出来ないことがあるので気をつけましょう(docs)。

(全ての通信プロトコルで話をするとややこしくなるので)以降はMQTTを採用したこととして話を進めます。

直接使用 or IoT Hub Device SDK

さて、なにも考慮せずにMQTTでデバイスからAzure IoT Hubに接続してデータを投げつければ良いかというと、そういうわけではありません。たとえば、MQTTのCONNECTパケットのClientIdフィールドにはAzure IoT Hubに登録したデバイスIDを指定せよ!といった、Azure IoT Hub固有のルールがあります。このルールは「MQTTプロトコルの直接使用」というタイトルで、docsに書かれています。

でも、正直、MQTTプロトコルの直接使用は面倒です。わたしも何度か実装しましたが、面倒でした。誰か作っておいてくれよという感じがします😅。
そのまさに作っておいてくれたものが、IoT Hub Device SDKです。IoT Hub Device SDKは、デバイスエンドポイントに接続、通信するためのSDKです。Azure IoT Hubデバイス接続文字列から認証情報を算出してMQTT接続したり、D2Cメッセージを適切なMQTTトピックとMQTTペイロードにして送信してくれます。また、接続状態を管理して自動的に再接続してくれたりもします。

Azure IoT SDK for <開発言語> - 第一世代

このIoT Hub Device SDKは単独で配布されているものではなくて、他のSDK(Provisioning Device SDKやIoT Hub Service SDKなど)と一緒にして開発言語別にAzure IoT SDK for XXXという名称のSDKで提供されています(docs)。現在、提供されている開発言語は.NETやPython, Node.js, Java, Cです。

Azure IoT SDK for .NETPython, Node.js, Javaは利用が簡単です。たとえば、Azure IoT SDK for PythonPyPIにパッケージがアップロードされているので、pipでエイッとやればインストール、利用することができます。これら4つのAzure IoT SDKLinuxWindowsなどのリッチなOS向けで、デバイスMPU(Microprocessor)のものになります。ラズパイとかラズパイとか。

Azure IoT C SDKs and Librariesは他と違ってややこしいです。このSDKはベースとなるライブラリの提供で、そのまますぐに使うことはできません。このSDKを使って、各OS(プラットフォーム)向けにアレンジしたものが別途提供されています(packages)。このAzure IoT SDKはリッチなOSに加えて、RTOSやベアメタルでも動かすこともできる構造になっています。Cコンパイラが使えてフラッシュメモリやRAMがそれなりに載っているMCU(Microcontroller)なら、このSDKコンパイルして利用できます。

Azure SDK for Embedded C - 第二世代

その後、Azure IoT SDKの第二世代が追加されました(docs)。

第二世代のターゲットは、ずばり、フラッシュメモリやRAMなどが少ないMCU(Microcontroller)向けです。とにかくメモリリソースの消費を最小限にするよう、さまざまな情報をポインタ参照で実装されています。また、SDK内部ではメモリの動的確保が完全に排除されています。

Generation 1と比べて、かなりの部分がそぎ落とされていて利用者にそれなりの技量を求められるからなのか、特定RTOS向けに実装を追加したAzure IoT Middlewareも提供されています。FreeRTOS向けに実装を追加したAzure IoT Middleware for FreeRTOSと、Azure RTOS向けに実装を追加したAzure IoT Middleware for Azure RTOSの2つが提供されています。これらは、コア部分はAzure SDK for Embedded Cですが、Azure IoT C SDKs and Libraries相当に扱いやすい機能が追加されています。

まとめ

  • バイスからAzure IoT Hubへの通信はデバイスエンドポイントに接続
  • バイスエンドポイントにMQTTやAMQPの自前コードから通信できますが、IoT Hub Device SDKを用いたほうが楽
  • MPUは、Azure IoT SDK for .NET, Python, Node.js, JavaもしくはAzure IoT C SDKs
  • MCUは、Azure IoT C SDKsもしくはAzure SDK for Embedded C

次回は、Azure IoT C SDKsとAzure SDK for Embedded Cの違いをもう少し詳しく書こうと思います。