I’m home
いつかのブログにも書いたかもしれないが、RaspberryPiで色々センサーをいじれるように遊んでいると、「自分が家にいるときだけ」という処理をしたくなる。
しかし、近接センサーは近くしか見ないし、照度センサーは窓の近くだと結構変わるし、わざわざそのためにBLEを使うのも……。
という場合に、簡単な方法として、自分のスマホのIPへpingを打って返り値を確認するという方法がある。
家に無線LANの環境があり、スマホだけ自宅にあるという状態がないのが前提である。
せっかくRaspberryPiなのにセンサー使わないのかよ!というのはあるが、手段よりも目的重視で……。
Photo by geralt | Pixabay / CC BY 0
スマホの準備
まず、自分のスマホを固定IPにしておく。DHCPで他のマシンに取られないように、ちょっと外れた番号にしておくと良い。たとえば192.168.1.20など。
Linuxのpingは止めるまで打ち続ける仕様
Windowsのコマンドプロンプトから打つと数回で勝手に止まるが、Linuxから打つと無限に打ち続けるようだ。いつも無意識に止めていたから気が付かなかった。
しかし、無限に打ち続けられてしまうと返り値が取得できない。
どうせなら失敗したら返ってくるとか、成功するまでは打ち続けるとか、そのようなオプションがあれば楽だったが、見当たらない。
しかたがないので、指定した回数だけpingを打って、一旦その結果を取得して、その結果によって更にループさせたりbreakさせたりする必要がある。
指定した回数だけpingを飛ばす
指定した回数だけ実行させるには、-cのオプションをつける。
ping -c 回数 192.168.1.20
今回の目的では、1回pingを実行してスリープさせて、またpingを実行して、のループがいいだろう。
サンプルコード
PING_TARGET="192.168.1.20"
MAX_SECOND=108000
SLEEP_SEC=5
count=$MAX_SECOND
success_count=0
THRESHOLD=5
while [ $count -ge 0 ] ; do
ping ${PING_TARGET} -c 1 >> /dev/null
rc=$?
if [ $rc -eq 0 ] ; then
if [ $success_count -eq $THRESHOLD ] ; then
break
fi
success_count=`expr $success_count + 1`
else
success_count=0
fi
sleep $SLEEP_SEC
count=`expr $count - $SLEEP_SEC`
done
if [ $rc -eq 0 ] ; then
fi
変数は適当に変える。
このサンプルは、5秒に一度pingを打ち、5回連続で成功すればbreakして、処理を実行する。
最大待ち時間は、約108000秒(6時間)にしてある。
このコードは、自宅に帰ったら勝手に照明をつけるためにRaspberryPiに仕込んでいるコードの抜粋である。
このスクリプトを、仕事の定時にcrontabで自動実行するようにしている。
すると、定時~6時間以内に家に着けば、勝手に電気がついてくれる。
ちなみに、シェルスクリプトのデバッグで困ったときは、
の部分を、
#!/bin/sh -x
に変更すると、行ごとの処理をすべて表示してくれるのでわかりやすい。
問題点
問題点は、自宅にいながらスマホの電源が切れたりwifiが切れたりした場合である。
そのあたりは反応性の良さとのトレードオフなので、しきい値やチェック間隔を調整していい感じにしよう。