こんにちは、さくらインターネット研究所の菊地です。
sakura.ioは、IoTデバイスをインターネットに接続する手段として、さくらインターネットが提供している通信モジュール込みのIoTプラットフォームのサービスです。IoTデバイスやサービスを開発しようと考えている皆さん、IoTデバイスをインターネットに接続する手段、どうしていますか?実はそこは結構難しいですよね。sakura.ioの通信モジュールを使うと、IoTデバイスの状態をインターネット側から把握したり、逆にインターネット側からIoTデバイスを制御したりということが簡単にできるようになります。使うのは簡単ですし、通信モジュールの費用、通信単価、共に安いのでおすすめです(以上宣伝)。
さて、sakura.ioには、IoTデバイスとインターネット側(正確にはさくらのIoTプラットフォーム)との間でデータをやり取りする基本機能の他に、ファイル配信機能もあります。これはIoTデバイスのファームアップデートなどを想定した機能なのですが、これを利用するとデバイスに対してバックドア的に設定を送り込む、ということも可能になるのです。
今回、sakura.ioのファイル配信機能を使って、Raspberry Pi 3(以下ラズパイ)のWiFi接続設定をリモートから送り込み、ラズパイでの設定なしにWiFiに自動で接続させる、というシステムの試作をしてみました。例えばラズパイをどこか出先などに持っていったときに、現地のWiFiにすぐにつなげる、といったことが実現できます。
もちろん、sakura.ioそのものの機能としてデバイスとネットがLTE経由ですぐに繋がるのですが、あえてWiFiで接続したい用途もあるかもなあ、というのがこの試作の想定です。また、(今回はやっていませんが)WiFi設定ではなく他の設定を送り込むことも原理的には可能ですので、ネットワーク機器に対する安全装置としても応用可能だと思います(そのような製品も最近増えていますね)。LTE回線を用いるsakura.ioの特徴を活かした使い方とも言えると思います。
以下のような構成で説明します。
- システム構成
- ラズパイへの設定
- sakura.ioコントロールパネルでの設定
- ファイル配信元サーバの設定
- 動かし方・動作状況
- まとめ
なお、以下の説明はある程度「わかる」人を想定しています。特にsakura.ioの基本的な使い方は簡単ですので、ここで触れてない部分については、いくらか試行錯誤してみて下さい。
1. システム構成
ラズパイとsakura.io(通信モジュール)の他に、ラズパイに送り込む設定ファイルを保持するwebサーバ(=ファイル配信元サーバ)が必要です。ファイル配信元サーバはインターネット側からアクセス可能な環境である必要があります。今回は、さくらのクラウド上にその環境を構築しています。
2. ラズパイへの設定
ラズパイとsakura.io通信モジュールを接続します。今回は、sakura.ioのRaspberry Pi ハット(試作品)を使っています。(ハットが一般発売されるまでは、ブレイクアウトボードを使うことになると思います。)
sakura.ioをラズパイで使うにあたっては、Pythonライブラリ(python-sakuraio)が提供されていますので今回はそれを使います。
- ライブラリ一覧 – sakura.ioドキュメント
- ライブラリ自体はgithubに公開されています
python-sakuraioライブラリはpython3系ですので、python3をインストールしておきます。なお余談ですがpyenv系は使わないほうが楽だと思います。今回はroot権限が必要な動作になるため、ユーザディレクトリ配下に環境が作られるpyenv系では、今回作成のスクリプトを動作させる時に実行パスやライブラリが見つからないなどの問題が発生しがちです(実際しました)。
python3、python-sakuraioライブラリをインストール完了した段階で、sakura.ioが正常動作しているか確認しておきましょう。ライブラリに含まれるサンプルプログラム(getuniqid.py)などを動かしてみて下さい。なお、初めて使う場合には、先立ってsakura.ioのコントロールパネル側での設定も必要です。
sakura.ioそのものが動いていることが確認できたら、今回のWiFi自動設定スクリプトをダウンロードします。
filereceive.pyが本体、led_flash.pyはWiFi設定がなされたときに観測可能なようにラズパイ本体のオンボードLEDを点滅させるためのサポートファイルです。LED点滅が不要であれば、filereceive.py内の当該行(9行目および127行目)をコメントアウトして下さい。led_flash.pyを動作させるためには、LEDの状態をファイルシステム上から制御できるように設定しておく必要があります。こちらを参考に設定(点滅トリガをnoneにする)して下さい。
なお、このスクリプトはあくまで動作サンプルとして公開しているものであり、実際の製品で使用できるようなレベルのものではありません。ご了承の上参照下さい。
3. sakura.ioコントロールパネルでの設定
sakura.ioのファイル配信機能は、IoTデバイスに配信したいファイルそのものをsakura.ioのコントロールパネル上にアップロードするのではなく、sakura.ioコンパネ上で配信したいファイルの置き場所(URL)を指定しておく、そして、IoTデバイス(通信モジュール)からのトリガでsakura.ioのIoT-PF側が当該ファイルを取得してデバイスにダウンロードする、という方式になっています。
- ファイル配信仕様 – sakura.ioドキュメント
具体的な設定方法ですが、sakura.ioコンパネから「ファイル配信」設定をクリックします(下記test_projectウィンドウ内の右上あたり)。
ファイル配信設定画面で2つのファイルの配信の設定をします。1つ(ファイル番号1)を「ダウンロード先パス名(=ラズパイのファイルシステム上のどこにファイルを置くか)」を指定するために、もう1つ(ファイル番号2)を「ダウンロードファイルそのもの」を指定するために使います。サーバアドレスやファイル名は適当に設定して下さい。
4. ファイル配信元サーバの設定
sakura.ioコンパネでの設定内容に合わせて、ファイル配信元サーバ(=www.kikuzo.jp)でダウンロード先パス名とダウンロードファイルを公開する様に設定します。今回はさくらのクラウドに立てたubuntuサーバを使っていますが、ファイルの公開ができればなんでもOKです。
こういう具合にファイルを用意します。
ubuntu@host01:~/sakuraio$ ls -l total 20 -rw-rw-r-- 1 ubuntu ubuntu 254 Jul 10 13:54 content -rw-rw-r-- 1 ubuntu ubuntu 29 Jul 7 16:01 content_config -rw-rw-r-- 1 ubuntu ubuntu 40 Jul 12 17:05 filepath -rw-rw-r-- 1 ubuntu ubuntu 30 Jul 7 15:56 filepath_config -rw-rw-r-- 1 ubuntu ubuntu 215 Jul 6 12:09 webserver.py ubuntu@host01:~/sakuraio$
各ファイルの内容は以下の通り。
filepath_configはダウンロード先パス名が実際に書き込まれているURLを指定します。
ubuntu@host01:~/sakuraio$ cat filepath_config http://www.kikuzo.jp/filepath ubuntu@host01:~/sakuraio$
filepathに、ラズパイ上のパス名を指定します。WiFi設定は/etc/wpa_supplicant/wpa_supplicant.confですので、そのように書いておきます。
ubuntu@host01:~/sakuraio$ cat filepath /etc/wpa_supplicant/wpa_supplicant.conf ubuntu@host01:~/sakuraio$
content_configはダウンロードファイルのURLを指定します。
ubuntu@host01:~/sakuraio$ cat content_config http://www.kikuzo.jp/content ubuntu@host01:~/sakuraio$
contentは、wpa_supplicant.confの内容になります。
ubuntu@host01:~/sakuraio$ cat content ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev update_config=1 network={ ssid="sakura-guest" #psk="abcdefghij" psk=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx proto=WPA2 pairwise=CCMP key_mgmt=WPA-PSK auth_alg=OPEN } ubuntu@host01:~/sakuraio$
SSIDや(暗号化された)パスワードは、ラズパイをつなぎたいWiFi-APのSSIDやパスワードを設定して下さい。その他暗号化方式なども適切に設定して下さい。そもそものこのファイルの書き方自体については「Raspbian 8.0 (jessie)で無線LANを使う」などを参照して下さい。
準備ができたら、これらのファイルを公開します。今回はお試しということでpythonでwebサーバを立ち上げています。webserver.pyというpyファイルを用意しましたが、コマンドライン実行でもできるようです。
ubuntu@host01:~/sakuraio$ sudo python webserver.py serving at port 80
5. 動かし方・動作状況
ここまでの準備ができたら、WIFi自動設定スクリプトがきちんと動作しているか確認します。コマンドラインから以下のようにスクリプトを起動して、/etc/wpa_supplicant/wpa_supplicant.confが書き換えられ、(自動的にリブートすることで)WiFi-APへ接続できているか確認します。
pi@raspberrypi:~/sakuraio $ sudo python3 filereceive.py /home/pi/sakuraio/sakuraio/python-sakuraio/sakuraio/hardware/rpi/__init__.py:40: RuntimeWarning: This channel is already in use, continuing anyway. Use GPIO.setwarnings(False) to disable warnings. GPIO.setup(self.mosi, GPIO.OUT) /home/pi/sakuraio/sakuraio/python-sakuraio/sakuraio/hardware/rpi/__init__.py:41: RuntimeWarning: This channel is already in use, continuing anyway. Use GPIO.setwarnings(False) to disable warnings. GPIO.setup(self.clk, GPIO.OUT) /home/pi/sakuraio/sakuraio/python-sakuraio/sakuraio/hardware/rpi/__init__.py:42: RuntimeWarning: This channel is already in use, continuing anyway. Use GPIO.setwarnings(False) to disable warnings. GPIO.setup(self.cs, GPIO.OUT) Get_file_metadata: Status: 0 Get_file_metadata: Filesize: 40 Get_file_metadata: Timestamp: 2017-07-18 03:44:07.075000 ... (続く)
ワーニングが出ますが無視して下さい(動作には問題ありません)。
確認が済んだら、WiFi自動設定スクリプトが起動時に自動で実行されるようにします。/etc/rc.localでスクリプトが自動で実行されるようにします(太線部が追加した部分)。
pi@raspberrypi:/etc $ cat /etc/rc.local #!/bin/sh -e # # rc.local # # This script is executed at the end of each multiuser runlevel. # Make sure that the script will "exit 0" on success or any other # value on error. # # In order to enable or disable this script just change the execution # bits. # # By default this script does nothing. # Print the IP address _IP=$(hostname -I) || true if [ "$_IP" ]; then printf "My IP address is %s\n" "$_IP" fi # wlan0 automated configuration with sakura.io /bin/sleep 60 /usr/bin/python3 /home/pi/sakuraio/filereceive.py exit 0 pi@raspberrypi:/etc $
sleep 60は、(バッドノウハウですが)起動時にsakura.ioモジュールが安定動作するまでの待ち時間です。これをやらないとsakura.ioのファイル配信機能が正常に動作しないため、致し方なく入れています。お陰でラズパイの起動に大変時間がかかるようになってしまいます。
さて、すべての設定が完了したら、ラズパイをリブートしてみましょう。
2分かかって起動して、ターゲットのWiFi-APに接続できていれば成功です。
6. まとめ
今回は、sakura.ioを使ってバックドア的に設定を送り込むサンプルを作ってみました。
コードを見てもらえればわかると思いますが、スクリプト実行時(=ラズパイの起動時)に毎回設定ファイルをダウンロードする動作になっています。これは非常に無駄のある動作なのですが、sakura.ioのファイル配信機能にはファイルが更新されているかを確認する、いわゆるHTTPにおけるIf-Modified-Since相当の動作がないため、致し方なくこのような作りにしています。ここはリブート時に設定ファイルをダウンロードするのではなく、ラズパイ側での何らかのアクション(GPIOで接続したボタンを押すなど)により設定ファイル取得を実行するように構成したほうがエレガントでしょう。
sakura.ioはデバイスとインターネットをLTE回線経由で簡単接続するソリューションを提供する製品ですが、一方で、WiFiに接続したい、というニーズも(まだ)あるのかなと思っています。特に、デバイスをエッジノードに接続する、それも簡単に!、という手段が必要なのではと考えています。例えば、研究所ブログの前回の記事でも触れたAWSのGreengrassなどでは、デバイスがネットワークに接続する部分についてはdon’t careになっているわけです。今回ご紹介したやり方が、その一つの解になればいいなと考えています。
余. python-sakuraioの実行時warningを消すには
python-sakuraio/sakuraio/hardware/rpi/__init__.pyファイルの38行目に以下の行を入れておけば出なくなります(エラーメッセージの通り)。
GPIO.setwarnings(False)