ミッション 有線もWiFiもないところで温度データを測定する
電源もWiFiもない場所で温度データを離れた場所でモニターしたい!そんな要望に応えるためにTWE-Liteを使います。前回は、TWE-Liteを使って温度データを手元のPCに送信するところまでをやりました。今回は、Raspberry Piという小型のPCをゲートウェイとして利用し、Ambientというクラウドサービスにデータを送信し、送ったデータをグラフでみるというところまでやってみます。
全体の構成を考える
前回、TWE-LiteとPCの接続を試してみました。あれはあれで立派なIoTシステムです。もし、TWE-Liteの通信範囲内ですべてが完結するなら、たとえば、畑と家が100メートルしか離れていないなら、あれで十分かもしれません。
上の図は、IoTシステムにありがちなデータの流れを模式図にしたものです。前回の場合、左側で示すように、エンドデバイスに仕込んだTWE-LiteからZigBee通信により直接PC(サーバ)にデータを送信しています。
さきほど述べたように近距離の通信でよければこれで十分です。でも、出かけた先でもデータがみたいなあ、なんて要望には応えられません。そのような場合にはインターネット上にデータを置いてどこからでも見られるようにしたいものです。
そんなわけで、今回は、右側に示したように、インターネットに接続できるゲートウェイを経由してデータをサーバに送るようにします。このようにすると以下の利点があります。
- ゲートウェイでデータを選んだり加工したりできる
- 置き場所や稼働時間など自由度が高い
1についていうと、TWE-LiteにはアプリケーションIDというものがつけられていて、これが同じなら互いに通信が可能です。逆にいうと、アプリケーションIDが同じだと自分の知らないところからでも送られてきたデータを受け取ってしまいます。それに、平均データや積算データがほしくて個別データが必要ない場合など、その辺の処理をゲートウェイに任せることもできます。
次に2ですが、たいていサーバは普通のPC以上のものなので、高価だし消費電力も大きいです。このため、どこに置いてもいいってわけじゃありません。また、サーバはデータを受け取るだけではなくてデータを見たいという要望に応えるため、基本24時間稼働します。一方、ゲートウェイは運用の仕方によっては24時間営業でなくても良い場合があります。
今回はこのゲートウェイにRaspberry Pi3(以下ラズパイ)を使うことにします。ラズパイは5000円くらいで購入できるLinux PCです。消費電力も5W程度なので、普通のPCよりずっと少ないです。
最後にIoTシステムにはデータを管理するサーバが必要になります。これが結構めんどくさいのですが、今回は、AmbientというIoTデータ可視化サービスを利用します。とりあえず自分でサーバを用意しなくてもいいので助かります。
ラズパイの購入と設定
それでは、さっそくゲートウェイの準備に取り掛かります。このゲートウェイにラズパイを使うわけですが、買ってきたらいきなり使える最近のPCと違って、ラズパイの場合はちょっとめんどうです。がんばりましょう。
まず、ラズパイを買う必要があるのですが、ついでにいくつか必要になるものがあります。最小限必要なのは以下のとおり。
- ラズパイ本体 Raspberry Pi 3 Model B
- microSDカード(8GB、クラス4以上、できれば16GB、クラス10)
- 電源アダプタ(5V、2.5A)
- HDMIが接続できるモニタとケーブル
- USB接続できるキーボードとマウス
もし、SDカードのリーダ・ライタがないなら、それも必要ですし、HDMIがささるモニタがあればいいんですが、DVI端子しかない場合、HDMI-DVI変換ケーブルが必要です。VGAしかない場合、いちおうHDMIからVGAの変換用アダプタが売ってますが、うまくいくかどうかはわかりません。また、いわずもがなですが、当然のようにインターネットに接続できるPCが必要ですね。
材料がそろったら、設定です。具体的にいうとラズパイを動かすためのOSをSDカードに書き込む作業です。かきこんだSDカードをラズパイに差して電源をいれれば、とりあえず動くようになります。では行ってみましょう。
OSのダウンロードとSDカードへのコピー
まず、お使いのブラウザから以下のサイトへ行きます。
サイトへ行くと、NOOBSとRasbianが選択できるようになっていますが、今回はNOOBSを選びます。左側の黒い方です。
次のページが表示されたら、赤丸でしめされたDownload ZIPボタンをクリックします。サイズが大きいのでけっこう時間がかかります。
ダウンロードが終わったら、ファイルを解凍します(右クリック->すべて展開)。
SDカードをPCに差し、展開されたファイルをSDカードにコピーしたら完了です。
OSのインストール
次にOSをインストールします。SDカードをPCから抜いてラズパイに差します。
さらに、モニタ用HDMIケーブル、キーボードとマウスのUSBケーブルを差します。最後に電源ケーブルを差します。というのもラズパイには電源ボタンがないので、電源を差すと起動してしまうからです。
起動してしばらくすると、インストールのOSを選択する画面が表示されます。選択するといってもRaspbianしかないので、その左側のチェックボタンにチェックをいれ、左上のInstallボタンをクリックします。そうすると、確認ダイアログが表示されるのでYesをクリックします。
しばらく待っていると(10分くらい)、見慣れた(?)デスクトップが表示されます。
タイムゾーンの設定
時計を日本時間にあわせます。デスクトップ左上Menuボタン->Preference->Raspberry Pi Configurationを順に選択していくと以下のような設定用のダイアログが表示されます。
Localisationタブ(一番右)のSet Timezoneをクリックし、AreaをAsia、LocationをTokyoにして、OKをクリックします。
キーボードの設定
Set Timezoneボタンの下にSet Keyboardボタンがあるのでこれをクリックし、CountryをJapan、VariantをJapanese(OADG 109A)にしてOKをクリックします。
ネットワーク接続
LANケーブルを差すだけで接続できるはずです。またWiFiで無線接続したい場合は、少々ややこしいのでまた今度。
電源の切り方
電源を切るときは、MenuボタンからShutdownを選択します。そうするとダイアログが表示されるので、さらにShutdownボタンをクリックします。このとき、すぐに電源をぬいてしまうと、シャットダウンのプロセス中に電源がなくなってしまい、場合によっては壊れるので、緑色のLEDの点滅がおわり赤の点灯(ついたまま)だけの状態になるまで待ってから電源をぬいてください。
TWE-Liteからのデータを受け取る
ここまでの作業でラズパイがふつうのPCとして使えるようになったので、TWE-Liteからのデータを受け取ってみます。ラズパイの空いているUSBポートにMonoStickを差し込み、送信側の電源もいれてください。これだけで受信されているのですが、ちゃんと受信しているかどうか確認するために、前回使ったTeratermと同様のアプリケーションをインストールします。
まず、コマンドライン入力のために、LXTerminalを起動します。
デスクトップ左上にあるLXTerminalのアイコンをクリックすると黒い画面が表示されるので以下のコマンドを入力します。
$ sudo apt-get update
$ sudo apt-get install cu
$ cu -s 115200 -l /dev/ttyUSB0
cuというアプリケーションをインストールし(2行目)、起動しています(3行目)。一行目は、インストールする対象となるアプリケーション(パッケージ)のリストを更新しているものです。インストール前の呪文だと思って実行してください。
3行目を実行すると上のように受信していることがわかります。
Ambientへの登録
IoTのためのクラウドを提供しているAmbientにユーザー登録しましょう。Ambientのトップページからユーザ登録できます。
トップページ右上のユーザー登録ボタンをクリックし、次の画面で、メールアドレスとパスワードを入力して送信すると、確認メールが送られてきます。メール内のURLにアクセスすると登録が完了します。
Ambientのチャネル生成
Ambientでは、データをチャネルという単位で管理します。
ログインすると上の画面があらわれます。登録したばかりなのでまだチャネルがひとつもありませんが、チャネルを作るボタンをクリックするだけで新しいチャネルが生成されます。
Ambientにデータを送信する
準備ができたのプログラムの作成に取り掛かりたいとおもいます。まず、Ambientに接続するためのライブラリが用意されているのでこれをインストールしておきます。先ほど使用したLXTerminalから以下のコマンドを入力します。2行目はインストールできたかの確認だけなので不要ですが、いちおう、バージョン確認のためやってみてください。今回は0.1.4でした。
$ sudo pip3 install git+https://github.com/AmbientDataInc/ambient-python-lib.git
$ sudo pip3 freeze | grep ambient
ambient==0.1.4
プログラミングのための環境を起動しましょう。今回はPython3を使用します。デスクトップ左上のラズパイアイコンからプログラミング->Python 3 (IDLE)を選択します。すると、Python 3.4.X Shell(Xは数値)というウィンドウが現れますので、File -> New Fileを選択して新しいファイルを作成します。
では、さっそくプログラムを書きこんでみましょう。まずは、Ambientに疑似データをおくってみます(各行#以降はコメントですので、その部分は不要です)。
import ambient #ライブラリの読み込み
chId = "****" #チャネルID
writeKey = "****************" #ライトキー
am = ambient.Ambient(chId, writeKey) #Ambientインスタンスの生成
r = am.send({'d1': 20}) #データの送信
print(r.status_code) #ステータスコードの確認
まず、ライブラリを読み込みます。チャンネルIDとライトキーは伏字にしてますが、実際には先ほどチャネル生成してできたチャネルのチャネルIDとライトキーを入力してください。これらの値を引数にしてAmbientインスタンスを生成します。あとはこのAmbientインスタンスに頼めばデータを送ってくれるわけです。実際には、sendメソッドを使って送信します。sendメソッドの引数は、JSON形式です。JSON形式はキーと値をセットにした文字列をカンマ区切りで並べたもので、全体を中かっこで囲みます。キーにはd1~d8まで使用できます。値には、温度や湿度といった測定データなどにします。
ファイルを保存したら、そのままキーボードのF5キーを押すと実行されます。うまくいけば、200という文字が帰ってくるはずです。これはプログラムの最後の行で返ってきたステータスコードを表示しているからです。
TWE-Liteからのデータを受け取りAmbientに送る
いよいよ本題です。TWE-Liteから定期的に送られてくるデータをAmbientに送ります。そのためには、最低限、以下の要素が必要になります。
- データが送られてきたタイミングでデータを取り出す。
- データをAmbientが受け取れるよう整形し、送信する。
順にやっていきましょう。
データが送られてきたタイミングでデータを取り出す
先ほどcuというアプリケーションでTWE-Liteから受け取ったデータをLXTerminal上に表示しました。これを同じようなことをするプログラムをPython3で書いてみます。新しいファイルを作成して以下のプログラムを書きこみ実行してください。
import serial #シリアル通信のためライブラリを読み込む
#シリアルポートを開く
port = serial.Serial("/dev/ttyUSB0", 115200, timeout=10)
#無限ループで受信待ち
while True:
line = port.readline() #文字列の読み込み
print(line) #文字列の表示
Monostickが差してあって送信側TWE-Liteが働いていれば、さきほどcuで表示されたのと同じような文字列がPythonシェルに表示されていきます。
プログラムはシリアル通信のためのライブラリを受け取った文字列を逐次表示するものです。while文による無限ループで何度も受信することができます。無限ループにしないと何も受け取らないままプログラムが終わってしまいます。
ここまでは簡単ですね。ただこのプログラムではTWE-Liteからのデータ受信がないときでも一秒ごとに行の読み取りを行っています。欲しいのはTWE-Liteからのデータだけなので、そのタイミングでデータを取り出すことにします。
import serial
port = serial.Serial("/dev/ttyUSB0", 115200, timeout=10)
while True:
line = port.readline()
line = line.decode('utf-8') #文字列をUTF-8に変更
d = line.split(";") #セミコロンで区切ってデータを配列に変換
if(len(d) == 13): #データの数が13個
value = float(d[7])/100.0 #8番目のデータが温度×100
print(value)
上記のプログラムを実行すると、TWE-Liteから温度データを受信した時だけ、温度の値を表示します。
データをAmbientが受け取れるよう整形し、送信する
後は、データを受信したタイミングでAmbientにデータを送るだけです。
import serial
import ambient
port = serial.Serial("/dev/ttyUSB0", 115200, timeout=10)
chId = "****"
writeKey = "****************"
am = ambient.Ambient(chId, writeKey)
while True:
line = port.readline()
line = line.decode('utf-8')
d = line.split(";")
if(len(d) == 13):
value = float(d[7]) / 100.0
print(value)
r = am.send({'d1': value})
これでAmbientにデータが送られています。
Ambientでデータをみてみる
それでは、Ambientにちゃんとデータが送られているかどうか確かめてみましょう。AmbientにログインしMyチャネルのページからチャネル名をクリックしてします。下のようなページが表示されます。
チャート追加ボタンをクリックします。以下のダイアログが表示されるので、d1の「左軸」にチェックをいれます。グラフ名は適当に。
チャートを追加ボタンをクリックすると、グラフが表示されます。
これで最低限の目標は果たしました。次回は、プログラムに少し手をいれてエラーの発生などに対応するようにしたいと思います。