こんにちは。家族で水族館に行った翌日、妻から「水族館連れて行ってもらって楽しかった?お父さんにお礼言いなさい」と言われた娘が嬉しそうに「おれい!」と言ったのを聞いてお礼言われて嬉しいとともに日本語って難しいと思った木村です。
この記事はAADOJOアドベントカレンダーの22日目の記事です。昨日はバックエンドのコードも書くネイルのステキなスーパーインフラエンジニアかとぅーん(VideoIndexerの「獄門」で爆笑しました)、明日はMVP2冠に輝くアルティメットデザインアーキテクトのりじパイセンと、これまたすごい方達に挟まれて緊張していますが頑張ります。
ふと検索して気づいたんですけど、24日目の深井さんはWikipediaに個人ページあるんですね。凄い。
この記事は
SORACOM LTE-M ButtonをAzure IoT Hubに接続してみたというお話です。SORACOM LTE-M ButtonならびにそれをAzure Functionsにつなぐという記事を先日公開していますので、まずはそちらを一読していただけますと幸いです。
なお、今回も記事中で「ボタン」と書いた場合は「SORACOM LTE-M Button for Enterprise(しろボタン)」または「SORACOM LTE-M Button Plus(ひげボタン)」を指します。
Azure IoT Hub
Azure IoT Hubは、IoTデバイスとクラウド処理との間で双方向通信やデバイスの接続管理などを一元的に行ってくれるサービスです。
先日の記事ではSORACOM BeamとSORACOM Funkを使って、ボタンのデータをAzure Funcitonsに接続しましたが、最終的にデータ処理をFunctionsでやるにしても、AzureでIoTといえばやはりIoT Hubに接続したくなりますよね?
ということで早速試してみることにします。*1
SORACOMサービスとIoT Hubとボタン
SORACOMサービスでAzure IoT Hubに接続するということで資料を探すと、SORACOMの公式ドキュメントに「SORACOM Beam を使用して Azure IoT Hub と X.509 証明書で認証した接続をする」というのがあります。
おお、この通りにやればうまく行きました!・・・では記事になりませんし、残念ながらボタンだとこの方法ではうまくいきません。
なぜなら、こちらのドキュメントで取り扱っているのは「IoT HubにMQTTで接続する」場合についてなのですが、SORACOM BeamのMQTTエンドポイント機能は「デバイスからSORACOMプラットフォームに対してMQTTで送られたものを、MQTTまたはMQTTSでクラウドに接続する」というものです。 しかし、今回対象となるボタンからSORACOMプラットフォームへはデータはUDPで送られているので、Beamで使えるのは「UDPtoHTTP」です。そのため、このドキュメントのままではうまくいかないのです。
ではどうすればよいのか? これは、UDPtoHTTPを使うわけですので、「IoT HubにデバイスからHTTPSで接続」できれば良いということになります。
HTTPSでIoT Hubに接続する
IoT Hubに接続する場合に参考になるのはこちらの公式ドキュメントです。
HTTPSについては「プロトコルの詳細」の所に以下のように書いてあります。
HTTPS では、 Authorization 要求ヘッダーに有効なトークンを含めることによって認証を実装します
そして、トークンについては同じページ内の「セキュリティ トークン」の辺りを参照します。公式ドキュメントではプログラムを作成してセキュリティトークンを作成する方法と、cliを用いる方法が書いてあります。今回はcliでやってみようと思います。
なお、本記事ではazコマンドのインストールやセットアップについては省略します。また、コマンドはbashでの例ですがpowershellでも同様です。
まず、IoT Hub用のエクステンションをインストールします。
az extension add --name azure-iot
リソースグループを新規に作成し、そこにIoT Hubを作成します。
RgName=[リソースグループ名] HubName=[IoT Hub 名] az group create -n ${RgName} -l japaneast az iot hub create -n ${HubName} -g ${RgName} --sku F1
デバイスを作成します。
DeviceId=[デバイスID] az iot hub device-identity create --device-id ${DeviceId} --hub-name ${HubName}
セキュリティトークンを取得します。--du
は期限を秒数で指定します。デフォルトは3600秒です。
az iot hub generate-sas-token --device-id=${DeviceId} -n {$HubName} --du 3600
セキュリティトークンはSharedAccessSignature sr=(Hubの名前).azure-devices.net%2Fdevices%2F(デバイスID)&sig=xxxx&se=xxx
という形になっていますので、これをメモします。
また、デバイスにデータが届いたかを確認できるよう、Azure IoT Explorer(以下、IoT Explorer)をインストールしておきます。
接続文字を以下のコマンドで取得し、IoT Explorerの「Add connection」から貼り付けます。
az iot hub connection-string show -n ${HubName} --key primary --query connectionString
接続できたら表示されているIoT Hubを開きます。先ほど作成されたデバイスがあるのでそれを開き、左メニューの「Telemetry」を選び、上の「Start」を押すとデバイスに届いたデータを確認できます。
SORACOM Beamで接続する前に、一度データを送れるかcurlコマンドで確認します。HTTPSでデータを送る場合、https://${HubName}.azure-devices.net/devices/${DeviceId}/messages/events?api-version=2015-08-15-preview
というURLにPOSTします。その際にHTTPヘッダーとしてAuthorization: 先ほど取得したセキュリティトークン
を付けるのを忘れないようにします。
curl -X POST https://${HubName}.azure-devices.net/devices/${DeviceId}/messages/events?api-version=2015-08-15-preview -H 'Authorization: SharedAccessSignature sr=*******' -h 'Content-type: application/json' -d '{"name":"http post test"}'
curlコマンドを実行してエラーメッセージが出なければ成功です。IoT Explorerには以下のように表示され、正しく送信されていることが分かります。
確認が終わったら上のメニューの「Stop」を押しておきましょう。
SORACOM Beamを設定する
HTTPSでデータを送れることが確認できたので、SORACOM Beamを設定してボタンのデータを送れるようにしましょう。 前回の記事と同じようにSIMグループの設定でバイナリーパーサと簡易位置情報をONにし、Beamの「UDPtoHTTP」エントリポイントを設定します。
Beamの設定では、ホスト名には${HubName}.azure-devices.net
、パスには/devices/${DeviceId}/messages/events?api-version=2015-08-15-preview
を指定します。
そして、カスタムヘッダでAuthorization
とContent-type
を追加します。Authorization
の値は先ほどのアクセストークン、Content-type
はapplication/json
です。
設定を保存したら、ボタンのSIMをこのSIMをこのグループに所属させます。
実行する
では、実行してみましょう。IoT Explorerを起動してから、ボタンをポチッとします。
うまく行きましたね!
トークンの更新
実際に運用する場合、このままだとセキュリティトークンの期限が切れてしまいますので定期的に更新する必要があります。
soracom cliを使った以下のコマンドで更新できますので、--du
で指定した期限内に定期的にコマンドを動かすようにすることで自動更新は可能です。GroupIdには、SIMグループのIDを指定します。
GroupId=xxxxx soracom groups get --group-id ${GroupId} | jq '.configuration.SoracomBeam["udp://beam.soracom.io:23080"].customHeaders.Authorization.headerValue|="'"`az iot hub generate-sas-token --device-id=${DeviceId} -n ${HubName} --du 3600 --output tsv`"'"' | jq '.configuration.SoracomBeam["udp://beam.soracom.io:23080"]' | echo '[{"key":"udp://beam.soracom.io:23080","value":'`cat`'}]' | soracom groups put-config --group-id ${GroupId} --namespace SoracomBeam --body -
無理にワンライナーにしても見にくいだけですね(笑)
SORACOM Beamで接続するとセキュリティトークンをデバイス側に埋め込まないで済むので更新作業も非常に楽ちんです。デバイスが故障して交換した場合も、SIMグループに所属するSIMを変更するだけで済みますので、メンテナンスコストが下がるというメリットがあります。
まとめ
Azure IoT HubはHTTPSでのデータ受信も可能なので、これを使うことでSORACOM LTE-M Buttonをはじめ、MQTT通信を実装していない様々なデバイスを接続することも可能です。
ただし、HTTPSでの接続ではセキュリティトークンでの接続しかサポートされませんので、トークンの更新をどうするかを検討する必要があるのが注意点となります*2。
以上、皆さんの参考になれば幸いです。
実はこのシリーズ、もうちょっとだけ続きます。分量が多くなってしまったので残りはまた別の記事でお届けします。