Alternative Architecture DOJO

オルターブースのクラウドネイティブ特化型ブログです。

SORACOM LTE-M ButtonをAzure IoT Hubに接続する

こんにちは。家族で水族館に行った翌日、妻から「水族館連れて行ってもらって楽しかった?お父さんにお礼言いなさい」と言われた娘が嬉しそうに「おれい!」と言ったのを聞いてお礼言われて嬉しいとともに日本語って難しいと思った木村です。

この記事はAADOJOアドベントカレンダーの22日目の記事です。昨日はバックエンドのコードも書くネイルのステキなスーパーインフラエンジニアかとぅーん(VideoIndexerの「獄門」で爆笑しました)、明日はMVP2冠に輝くアルティメットデザインアーキテクトのりじパイセンと、これまたすごい方達に挟まれて緊張していますが頑張ります。

adventar.org

ふと検索して気づいたんですけど、24日目の深井さんはWikipediaに個人ページあるんですね。凄い。

ja.wikipedia.org

この記事は

SORACOM LTE-M ButtonをAzure IoT Hubに接続してみたというお話です。SORACOM LTE-M ButtonならびにそれをAzure Functionsにつなぐという記事を先日公開していますので、まずはそちらを一読していただけますと幸いです。

aadojo.alterbooth.com

なお、今回も記事中で「ボタン」と書いた場合は「SORACOM LTE-M Button for Enterprise(しろボタン)」または「SORACOM LTE-M Button Plus(ひげボタン)」を指します。

Azure IoT Hub

Azure IoT Hubは、IoTデバイスとクラウド処理との間で双方向通信やデバイスの接続管理などを一元的に行ってくれるサービスです。

先日の記事ではSORACOM BeamSORACOM 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に接続する場合に参考になるのはこちらの公式ドキュメントです。

docs.microsoft.com

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)をインストールしておきます。

f:id:showm001:20201214172535p:plain
Azure IoT Explorer

接続文字を以下のコマンドで取得し、IoT Explorerの「Add connection」から貼り付けます。

az iot hub connection-string show -n ${HubName} --key primary --query connectionString 

接続できたら表示されているIoT Hubを開きます。先ほど作成されたデバイスがあるのでそれを開き、左メニューの「Telemetry」を選び、上の「Start」を押すとデバイスに届いたデータを確認できます。

f:id:showm001:20201215105418p:plain
届いたデータを確認

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には以下のように表示され、正しく送信されていることが分かります。

f:id:showm001:20201215110109p:plain
送信結果

確認が終わったら上のメニューの「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を指定します。

f:id:showm001:20201215111055p:plain
SORACOM Beam設定(1)

そして、カスタムヘッダでAuthorizationContent-typeを追加します。Authorizationの値は先ほどのアクセストークン、Content-typeapplication/jsonです。

f:id:showm001:20201215111446p:plain
SORACOM Beam設定(2)

設定を保存したら、ボタンのSIMをこのSIMをこのグループに所属させます。

実行する

では、実行してみましょう。IoT Explorerを起動してから、ボタンをポチッとします。

f:id:showm001:20201216112557p:plain
ボタンのデータ受信

うまく行きましたね!

トークンの更新

実際に運用する場合、このままだとセキュリティトークンの期限が切れてしまいますので定期的に更新する必要があります。

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

 

以上、皆さんの参考になれば幸いです。

 

実はこのシリーズ、もうちょっとだけ続きます。分量が多くなってしまったので残りはまた別の記事でお届けします。

*1:SORACOMサービスと繋ぐ場合、デバイスの管理はSORACOM側で行われるし、ボタンはデータ受信は出来ないので双方向通信は不要、沢山のボタンを繋ぐ場合ならfunnelでEvent Hubsに送れる。ならば頑張ってIoT Hubに繋ぐ意味があるのか・・と気づいたあなた、鋭い。まぁそこは一旦置いといて・・・

*2:UDPtoMQTTがあると解決するので、ソラコムサンタにお願いします