Azure IoT HubでMQTTを試してみた

2022.08.05

こんにちは。CX事業本部Delivery部のakkyです。 クラスメソッドでは、IoTのプロダクトにはAWS IoTをメインで使っていますが、AzureやGCPにももちろんIoTのサービスがあります。 ドキュメントを読んだだけでも各社のサービスに違いがあり、それぞれ設計思想や想定しているユースケースが異なっているのではないかと思います。 さまざまなサービスを開発していく上で、AzureやGCPを知ることも必要だと考え、今回はそのうちAzureのIoTサービスを実験してみることにしました。

Azure IoT HubはAWSでいえばIoT Coreに相当するサービスで、デバイスとクラウドとのメッセージの中継、メッセージの他サービスへの中継を行うことができるフルマネージドサービスです。

まずは、クラウドとデバイスをMQTTで接続するところまでをご紹介します。

Azure IoT Hubの作成

Azureのアカウントを作ったら、Azure PortalからIoT Hubを検索し、作成をクリックして新たなIoTハブを作成します。リソースグループを新規作成し、IoT Hub名、リージョンを設定します。IoT Hub名は全世界でユニークな名前にする必要があります。

価格とスケールティアはF1: Freeレベルにします。Azure IoT Hubはメッセージ4KBごとに計算されるユニットという単位で料金が計算されます。(ユニット≠デバイスです)Freeエディションでは、無料で1日8000メッセージまで送信できます。なお、このプランから有料プランへはアップグレードできません。

作成をクリックすると、デプロイされます。しばらく待つと使用できるようになります。

デバイスの追加

まずはデバイスで使うクライアント証明書を作りましょう。 チュートリアル: Microsoft 提供のスクリプトを使用してテスト証明書を作成するで紹介されているスクリプトを使って、オレオレ証明書を作ります。

次のGithubリポジトリをCloneするかzipをダウンロードしてください。

https://github.com/Azure/azure-iot-sdk-c

tools/CACertificates/に含まれるスクリプトを使います。私はWSL上のUbuntu18.04で作業しました。

CA証明書の作成

まず、次のコマンドを実行し、CA証明書を作ります。

chmod +x ./certGen.sh
./certGen.sh create_root_and_intermediate

ここでできたcerts/azure-iot-test-only.root.ca.cert.pemを、IoT Hubの証明書→追加から適当な名前を付けてアップロードします。 所有証明が必要ですので、今アップロードした証明書の名前を選択し、「確認コードを生成します」をクリックして確認コードを表示させます。

次のコマンドを実行して、新しい証明書を生成します。

./certGen.sh create_verification_certificate <確認コード>

新たに生成されたverification-code.cert.pemをアップロードすれば、完了です。

デバイス証明書の作成

次にデバイス証明書を生成します。 次のコマンドを実行します。

./certGen.sh create_device_certificate mydevice

デバイス名は好きな名前を付けられるのですが、デバイス名やMQTTユーザー名にも使用するので、一貫した名前を使ってください。 このコマンドを実行するとcert/new-device.cert.pemとcert/new-device.cert.pfxという2つのファイルが生成されます。

MQTTでの接続には秘密鍵も必要なので、次のコマンドで.pfxから公開鍵と秘密鍵をPEM形式に変換します。

openssl pkcs12 -in certs/new-device.cert.pfx -clcerts -nokeys -out mydevice.crt
openssl pkcs12 -in certs/new-device.cert.pfx -nocerts -nodes -out mydevice.key

(ファイルの前方にBASE64でない文字列が入っているので、ツールによっては取り除く必要があるかもしれません)

デバイスの登録

ポータルのデバイス管理→デバイスから、デバイスを追加します。

デバイスIDには証明書と同じ名前を入力してください。認証の種類は「X.509 CA 署名済み」にします。「保存」をクリックするとデバイスが追加されます。

動作確認

VSCode拡張のインストール

Azureには、Visual Studio Code用の拡張機能がありますので、こちらを検証用に使います。 VSCodeの拡張機能からAzure IoT Toolsを追加してください。いくつかの拡張機能が一緒にインストールされます。

拡張機能が追加されたらログインしておきます。VSCodeのエクスプローラーにAZURE IOT HUBが追加されます。

デバイス→クラウドのメッセージ送信

VSCodeのAZURE IOT HUBから、Devices→mydeviceを右クリックし、「ビルドインエンドポイントのモニターを開始」をクリックします。

次に、デバイスに見立ててPC用のMQTTクライアントであるMosquittoを使用し、次のコマンドを実行します。 WSL上のUbuntuで実行しました。IoT Hubのエンドポイント名は適時変更してください。(iothub-akkyの部分)

mosquitto_pub -h "iothub-akky.azure-devices.net" -p 8883  -u "iothub-akky.azure-devices.net/mydevice" -t "devices/mydevice/messages/events/" -m '{"mes":"hello azure!"}' --capath /etc/ssl/certs/ --cert my
device.cer --key mydevice.key -i mydevice -d

VSCodeを見ると、メッセージが表示されていることが確認できました!

クラウド→デバイスのメッセージ送信

反対方向もやってみます。 次のコマンドでMosquittoをサブスクリプションさせます。

mosquitto_sub -h "iothub-akky.azure-devices.net" -p 8883  -u "iothub-akky.azure-devices.net/mydevice" -t "devices/mydevice/messages/devicebound/#"  --capath /etc/ssl/certs/ --cert mydevice.cer --key mydevice.key -i mydevice -q 0 -d

VSCodeでは、「デバイスへC2Dメッセージを送信」を選択し、送信するメッセージを入力します。

Mosquittoを見ると、きちんと{"mes":"from azure!"}が受信されていることが確認できました!

Client mydevice sending CONNECT
Client mydevice received CONNACK (0)
Client mydevice sending SUBSCRIBE (Mid: 1, Topic: devices/mydevice/messages/devicebound/#, QoS: 0, Options: 0x00)
Client mydevice received SUBACK
Subscribed (mid: 1): 0
Client mydevice received PUBLISH (d0, q0, r0, m0, 'devices/mydevice/messages/devicebound/%24.to=%2Fdevices%2Fmydevice%2Fmessages%2Fdevicebound', ... (21 bytes))
{"mes":"from azure!"}
Client mydevice sending PINGREQ
Client mydevice received PINGRESP
Client mydevice sending PINGREQ
Client mydevice received PINGRESP
^CClient mydevice sending DISCONNECT

おわりに

今回初めてAzureを使用しましたが、単にMQTTを使うだけでも設計思想の違いを感じました。

次回以降Azureの他のサービスと連携し、送信された値のモニタリングなどを試してみたいと思います。