外出時に自宅のラズパイが気になることありませんか?
ブラウザさえあれば、Azure Cloud Shellからアクセスできますので、紹介します。
仕組み
IoT Hub デバイス ストリーム
の機能を使います。2020/11/1現在プレビュー状態ですが、誰でも試すことが可能です。
Azure IoT Hub デバイス ストリームによって、さまざまな cloud-to-device 通信シナリオのセキュリティで保護された双方向 TCP トンネルの作成が容易になります。 デバイス ストリームは、デバイスとサービス エンドポイント間のプロキシとして機能する、IoT Hub ストリーミング エンドポイントによって仲介されます。
(画像は公式サイトのものです)
https://docs.microsoft.com/ja-jp/azure/iot-hub/iot-hub-device-streams-overview
IoT Hubが仲介することで、通常はファイアーウォールに防がれてアクセスできないRaspberry Piに外部からアクセスできるようになります。
環境
デバイス側
Raspberry Pi 3
Raspberry Pi OS (32-bit) Lite 最新版(2020-08-20)
セットアップ
以下の手順で進めます。
- Azure IoT Hubの設定
- デバイス(Raspberry Pi)側の設定
- サービス(Azure Cloud Shell)側の設定
1. Azure IoT Hubの設定
Azure IoT Hubの作成は、Azure Cloud Shellで実行します。
Azure IoT 拡張機能を追加
az extension add --name azure-iot
Azure IoT Hubを作成
無料のSKUで作成します。
デバイスストリームに対応しているリージョンは限られています。
- 米国中部
- 米国中部 EUAP
- 東南アジア
- 北ヨーロッパ
az iot hub create --name [IoT Hub名] --resource-group [リソースグループ名] --location centralus --sku f1 --partition-count 2
デバイスを作成
Raspberry PiがIoTデバイス扱いとなりますので、IoT Hubにデバイスを作成します。デバイスIDはraspberrypi
としました。
az iot hub device-identity create --hub-name [IoT Hub名] --device-id raspberrypi
接続文字列を取得
接続文字列は2種類必要です。
デバイス(Raspberry Pi)側で使用する接続文字列
az iot hub device-identity connection-string show --hub-name [IoT Hub名] --device-id raspberrypi --output tsv
サービス(Azure Cloud Shell)側で使用する接続文字列
az iot hub connection-string show --policy-name service --hub-name [IoT Hub名] --output tsv
これで、Azure IoT Hubの設定は完了です。
2. デバイス(Raspberry Pi)側の設定
つづけてRaspberry Piの設定です。
OSをインストールした直後の状態から進めたいと思います。
必要なソフトウェアのインストール
sudo apt install git cmake libssh-dev libcurl4-openssl-dev uuid-dev -y
デバイス側ソースの取得
パブリックプレビュー用ブランチを使用します。
git clone -b public-preview https://github.com/Azure/azure-iot-sdk-c.git
cd azure-iot-sdk-c
git submodule update --init
ソースの修正
azure-iot-sdk-c/iothub_client/samples/iothub_client_c2d_streaming_proxy_sample
にあるiothub_client_c2d_streaming_proxy_sample.c
にデバイス側で使用する接続文字列を指定します。(70行目です)
static const char* connectionString = "[device connection string]";
makeする
公式ドキュメントではmake -j
と書いてありますが、メモリ不足で失敗しますので、-j
は外しました。
cd ~/azure-iot-sdk-c/
mkdir cmake
cd cmake
cmake ..
make
makeが成功するとazure-iot-sdk-c/cmake/iothub_client/samples/iothub_client_c2d_streaming_proxy_sample/
にiothub_client_c2d_streaming_proxy_sample
が生成されます
わかり易い場所に移動します。
mkdir ~/bin
cp iothub_client/samples/iothub_client_c2d_streaming_proxy_sample/iothub_client_c2d_streaming_proxy_sample ~/bin/
自動起動の設定
serviceファイルを作成します。
[Unit]
Description=IoT Hub Client C2D Streaming Proxy
After=network.target
[Service]
ExecStart=/home/pi/bin/iothub_client_c2d_streaming_proxy_sample
WorkingDirectory=/home/pi/bin
StandardOutput=inherit
StandardError=inherit
Restart=always
User=pi
[Install]
WantedBy=multi-user.target
serviceを有効にして起動します。
sudo mv ~/iothub_client_c2d_streaming_proxy.service.service /etc/systemd/system/
sudo systemctl enable iothub_client_c2d_streaming_proxy.service
sudo systemctl start iothub_client_c2d_streaming_proxy.service
デバイス(Raspberry Pi)側の設定は完了です。
3. サービス(Azure Cloud Shell)側の設定
サービス側のサンプルはNode.jsで動作します。Azure Cloud Shellで提供されているNode.jsのバージョンはv8.16.0
ですが、v10以上が必要なので、まずはNode.jsをセットアップします。
Node.jsのインストール
wget https://nodejs.org/dist/v10.19.0/node-v10.19.0-linux-x64.tar.gz
mkdir ~/node
tar zxf node-v10.19.0-linux-x64.tar.gz -C ~/node/
cd node
ln -s node-v10.19.0-linux-x64 node
echo 'export PATH=~/node/node/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
サービス側ソースの取得
wget https://github.com/Azure-Samples/azure-iot-samples-node/archive/streams-preview.zip
unzip streams-preview.zip
mv azure-iot-samples-node-streams-preview/iot-hub/Quickstarts ~/
外部ライブラリーの取得
cd ~/Quickstarts/device-streams-service/
npm install azure-iothub@streams-preview
npm install
環境変数の設定
Node.jsのプログラムは環境変数を参照するようですので、必要な情報を環境変数にセットします。
IOTHUB_CONNECTION_STRING
にサービス側で使用する接続文字列をセットします。
※Azure CLIで取得して設定するように工夫してみました
echo 'export IOTHUB_CONNECTION_STRING="`az iot hub connection-string show --policy-name service --hub-name [IoT Hub名] --output tsv`"'>> ~/.bashrc
echo 'export STREAMING_TARGET_DEVICE=raspberrypi' >> ~/.bashrc
echo 'export PROXY_PORT=2222' >> ~/.bashrc
source ~/.bashrc
これでサービス(Azure Cloud Shell)側の設定は完了です。
接続
準備は整いましたので、実際に接続してみましょう。
デバイス側はもう特に触りませんので、Azure Cloud Shell上で作業します。
cd ~/Quickstarts/device-streams-service/
node proxy.js &
ssh pi@localhost -p 2222
Node.jsのProxyプログラムはフォアグラウンドで動作する仕組みなのでバックグラウンドで動作させます。
localhost(=Azure Cloud Shell)の2222ポートにSSHで接続することで、デバイス側に接続ができます。
Azure Cloud Shellのインスタンスが停止したあとでも、接続
の手順を行うとデバイス側に接続できます。
AzureのAndroidアプリからもこの通り。
これでいつでもどこでもRaspberry Piにアクセスできますね。
参考サイト
https://docs.microsoft.com/ja-jp/azure/iot-hub/iot-hub-device-streams-overview
https://docs.microsoft.com/ja-jp/azure/iot-hub/quickstart-device-streams-proxy-c
https://docs.microsoft.com/ja-jp/azure/iot-hub/quickstart-device-streams-proxy-nodejs