移動している中、IoT データを送信したいなと。この場合、WIFI がないんですよね。
IoT デバイスからはブルートゥースやWiFi でネット経由へデータは出せるのですが、どこでも、投げたいので Soracom Air の SIM を使い始めました。
電波が届く範囲なら、どこでも、データを投げて記録が取れるということで、まずは格安の Linux ボードで Soracom に接続し単純なデータを送信するところまでやってみました。
今回の目標は、「Soracom 経由で、Linux の CPU 温度を ThingSpeak に送信しグラフ化させる」のが目標です。
ThingSpeak とは、IoT データを記録し、グラフ表示するWEBサービスです。このサービスは、自前でも構築可能ですので最終的にはデータ蓄積するサーバを構築しても良さそうです。
これが実現できると、以下のようなグラフがリアルタイムで記録されます。
これを実現するためには、以下のような準備が必要です。
・Linux ボードの準備と、その OS の選定
・soracom sim の準備と Linux 側から PPP 接続するための USB モデムの設定
・CPU 温度を取得して thingspeak にデータを投げるスクリプト
・thingspeak 側のアカウントなどの準備
最終的には、自立して稼動させたいので電源周りをどうしようか課題は残ります。
・独立した電源まわりの準備
・電源に充電させる仕組
今回 Soracom 経由でインターネットに接続に利用する母艦の Linux ボードは、Orange Pi PC です。ラズベリーパイは、価格は5000円前後しますので屋外でぶっ壊れたときにショックなので、コストパフォーマンスが良い Orange Pi でやることに。
Orange Pi シリーズは、過去にも紹介していますが、種類が結構あります。最近発売された WiFi が付いてさらに格安の Orange Pi Lite というものもあります。こちらは約1700円程度で購入できます。人柱的に、このボードも入手中ですので、到着したら改めてレポートしてみたいと思います。
さて、soracom と 3G 通信するためにモデムが必要ですが、LGエレクトロニクス・ジャパン製で、OEM では DoCoMo から出ている L-05A を使いました。amazon で中古でゲットしました。osx でも使えるというのがぽちったポイントでした。
最終的には、もう少しコンパクトにして電池を組み込む予定です。応用すれば GPS モジュールを接続して、位置を補足する IoT デバイスも作れそうです。
soracom の管理コンソールからは、データ転送量も見えて管理しやすそうです。
では、順にポイントと勘所をご紹介します。
Linux ボードの準備と、その OS の選定
まず、母艦の準備です。Orange PI PC を用意しました。
http://www.orangepi.org/orangepipc/
オフィシャルサイトから、メーカー直販の aliexpress の販売サイトにいけます。メモリ512M でも要求は満たしますので、one とか lite でもよいかと思います。
OS は、ARMBIAN というものを今回は採用。Debian 系の OS となります。
http://www.armbian.com/orange-pi-pc/
8GB の SDCard に書き込みし、IP を固定しておきます。電源は、ラズベリーパイとは違い、マイクロUSBではありませんので、別途 4mm で、センターピンが 1.7mm のDC ジャックを用意しておきます。これは、PSP用USB充電ケーブルと同じなので、100円均一などでもゲットできるかと思います。自分は、ジャックを別途購入し電源ケーブルは自作です。
なお、今回はCPU ヒートシンクとファンを実装しました。設定によっては、ヒートシンクのみや、無しでも運用可能です。
設定によりますが、最高で100度近くまで CPU が発熱しますので寿命が短くなるか壊れる事もありますので注意が必要です。
過去にヒートシンクを付けた記事を書いていますのでご参考に。
OrangePi One にFan を付けて全開ベンチマーク
soracom sim の準備
次は、soracom の sim を USB モデムで使うための準備です。USB モデムは、今回中古で L-05A を購入しておきました。
まずは、soracom の sim をアクティベートしておきます。管理コンソールよりログインし、sim の操作で可能です。
なかなか簡単操作です。すばらしい。速度クラスは、とりあえず s1.minimum にしておきました。
データ通信量が 150MiB を超えたらメールしてくるようにしておきました。有効期限なども設定できるようですね。キャリアになった気分です。
Linux 側から PPP 接続するための USB モデムの設定
次に、sim を USB モデムに差込、Linux 機に取り付けます。デフォルトでは、CD-ROMドライブとして認識されるようですが、これは AT コマンドで挙動を制御できるようです。/dev/sr0 を一度イジェクトしておきます。
[root@opi 22:34:04 ~]# eject /dev/sr0
eject: unable to eject, last error: Invalid argument
[root@opi 22:34:12 ~]# ll /dev/ | grep ACM
crw-rw---- 1 root dialout 166, 0 May 26 22:34 ttyACM0
crw-rw---- 1 root dialout 166, 1 May 26 22:34 ttyACM1
crw-rw---- 1 root dialout 166, 2 May 26 22:34 ttyACM2
[root@opi 22:34:30 ~]#
そして、AT コマンドで CD-ROM ドライブとして認識しないよう設定しておきます。
[root@opi 22:34:49 ~]# screen /dev/ttyACM0
ATZ
OK
AT%USBMODEM=0
[0] MODEM DRIVER
OK
ATZ0
OK
あとは、ppp 接続するための設定をしておきます。wvdial パッケージを導入しておきます。
[root@opi 15:57:33 log]# apt-get install wvdial
設定です。
----- /etc/wvdial.conf
[Dialer Defaults]
Init1 = ATZ
Init2 = ATQ0 V1 E1 S0=0 &C1 &D2
Init3 = AT+CGDCONT=1,"IP","soracom.io"
Dial Attempts = 3
Modem Type = Analog Modem
Dial Command = ATD
Stupid Mode = yes
Baud = 460800
New PPPD = yes
Modem = /dev/ttyACM0
ISDN = 0
Phone = *99***1#
APN = soracom.io
Username = sora
Password = sora
Carrier Check = no
Auto DNS = 1
Check Def Route = 1
systemctl で起動できるよう設定しておきます。システム起動時に起動する設定にはまだしていません。enable にするだけですが。
---- /etc/systemd/system/wvdial.service
[Unit]
Description=wvdial service
Wants=network.target
[Service]
Type=simple
ExecStartPre=/sbin/route del default gw 192.168.1.1
ExecStopPost=/sbin/route add default gw 192.168.1.1
ExecStart=/usr/bin/wvdial
ExecStop=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target
以上で設定は終わり。接続の確認をしておきます。
[root@opi 16:02:24 log]# systemctl start wvdial
動作したかどうかは、status で見てみます。USB モデムの LED が緑から青色になっていると思います。
[root@opi 16:03:29 log]# systemctl status wvdial
::
May 28 16:02:37 orangepipc pppd[19681]: local IP address 10.182.126.96
May 28 16:02:37 orangepipc pppd[19681]: remote IP address 10.64.64.64
May 28 16:02:37 orangepipc pppd[19681]: primary DNS address 100.127.0.53
May 28 16:02:37 orangepipc pppd[19681]: secondary DNS address 100.127.1.53
May 28 16:02:37 orangepipc wvdial[19679]: –> local IP address 10.182.126.96
May 28 16:02:37 orangepipc wvdial[19679]: –> remote IP address 10.64.64.64
May 28 16:02:37 orangepipc wvdial[19679]: –> primary DNS address 100.127.0.53
May 28 16:02:37 orangepipc wvdial[19679]: –> secondary DNS address 100.127.1.53
プライベートなクラスAの IP が割り振られるようですね。ppp0 の状態を見ると以下のようです。
[root@opi 16:07:38 log]# ifconfig ppp0
ppp0 Link encap:Point-to-Point Protocol
inet addr:10.182.126.96 P-t-P:10.64.64.64 Mask:255.255.255.255
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:83 errors:0 dropped:0 overruns:0 frame:0
TX packets:83 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:3
RX bytes:10339 (10.0 KiB) TX bytes:14232 (13.8 KiB)
[root@opi 16:07:43 log]#
eth0 も繋がっていますが、ルーティング情報が以下のようになっていれば、ppp0 経由でインターネットに接続可能です。
[root@opi 16:09:42 log]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 0.0.0.0 0.0.0.0 U 0 0 0 ppp0
10.64.64.64 0.0.0.0 255.255.255.255 UH 0 0 0 ppp0
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
[root@opi 16:09:44 log]#
google までトレースルートしてみましょう。
[root@opi 16:11:03 log]# traceroute www.google.com
traceroute to www.google.com (172.217.25.68), 30 hops max, 60 byte packets
1 ec2-175-41-192-232.ap-northeast-1.compute.amazonaws.com (175.41.192.232) 97.266 ms 106.862 ms 106.923 ms
2 27.0.0.71 (27.0.0.71) 116.491 ms 136.763 ms 136.841 ms
3 52.95.30.79 (52.95.30.79) 146.299 ms 52.95.30.77 (52.95.30.77) 156.162 ms 52.95.30.83 (52.95.30.83) 166.192 ms
4 52.95.30.150 (52.95.30.150) 166.290 ms 52.95.30.144 (52.95.30.144) 166.450 ms 52.95.30.150 (52.95.30.150) 205.754 ms
5 52.95.216.117 (52.95.216.117) 185.674 ms 195.447 ms 205.659 ms
6 216.239.54.13 (216.239.54.13) 215.216 ms 79.420 ms 97.653 ms
7 108.170.233.79 (108.170.233.79) 117.188 ms 127.330 ms 146.963 ms
8 nrt13s50-in-f4.1e100.net (172.217.25.68) 156.867 ms 187.089 ms 196.809 ms
[root@opi 16:11:26 log]#
soracom のコンソールで 1 時間ごとの使用量を見ると、記録されているようです。
CPU 温度を取得して thingspeak にデータを投げるスクリプト
次は、cpu 温度を取得し、データを飛ばすプログラムを作ります。python で作りました。
#!/usr/bin/python
# coding: utf-8
import requests
#from time import sleep
import time
api_key='your api key'
def sender():
while True:
f = open("/sys/class/thermal/thermal_zone0/temp","r")
t = f.read()
payload = {'api_key': api_key, 'field1': str(t)}
f.close()
print "CPU Temp is:%s"%t ,
r = requests.get('http://52.7.53.111/update', params=payload)
print "Result: ", r.text
time.sleep(1.0)
def main():
sender()
if __name__ == '__main__':
main()
簡単にプログラムを補足します。
python のライブラリを以下のように入れておきます。
# apt-get install python-dev
# apt-get install python-pip
# pip install requests
api_key には、書き込みのAPI Key を入れておきます。
データをhttps (SSL)経由の post で投げるとパケットが消費されるので、ここでは、get で投げています。
api.thingspeak.com を名前解決すると以下のように2つIPが出ますので、ここでは片方のIPを指定しています。相手側の事情でIP が変わることもあるかもしれません。
# dig api.thingspeak.com
::
;; ANSWER SECTION:
api.thingspeak.com. 60 IN A 52.200.157.52
api.thingspeak.com. 60 IN A 52.7.53.111
プログラムを以下のように実行します。
[root@opi 18:20:46 work]# python t.py
実行すると、以下のようになります。
[root@opi 18:20:46 work]# python t.py
CPU Temp is:38
Result: 401
CPU Temp is:38
Result: 0
CPU Temp is:38
Result: 0
CPU Temp is:38
Result: 0
CPU Temp is:38
Result: 0
CPU の温度を上げるため、負荷を UnixBench でかけてみます。
[root@opi 18:08:33 UnixBench]# ./Run -c 4
グラフ表示は、こんな感じで出ています。
CPU 温度がこれで1秒ごとに記録されていきますが、600秒に一度くらいでいいので、修正し、ログオフ後もスクリプトが動作するよう以下のように nohup で実行しておきます。
[root@opi 18:34:08 work]# nohup python t.py &
[1] 13673
[root@opi 18:34:28 work]# nohup: ignoring input and appending output to ‘nohup.out’
[root@opi 18:34:32 work]# ps axu | grep python
::
root 13673 4.1 0.8 13796 8428 pts/0 S 18:34 0:00 python t.py
なお、今のところ soracom の接続料金は 119 円のようです。
しばらく、CPU 温度を記録させてテストしてみることに。GPIO からセンサーを取り付ければ、外気温や湿度、明るさや、PM2.5 など記録したいものを投げれます。
ちなみに、1日経過後、課金は以下のようです。
この母艦を利用し、WiFi 経由で センサーデバイスを作るのが実用的かもしれません。組み合わはいろいろありますね。
この続きはまたの機会に。