部屋に入るとファミマの入店音が鳴るアプリ(RaspberryPi + Node.js + iBeacon)

みなさん、ファミチキ食べてますか？
私はコンビニではファミマが一番好きです。

でも、あまりに日々欠かさず毎日ファミマに通っていると、
**「あいつまたファミチキ買ってるよ、プークスクス」**
とか言われないかと心配になってきますよね。

ちょうどiBeaconが手元にあるので、
自宅に帰るとファミマの入店音が鳴る仕組みを作って、
自宅でファミマ気分を味わってみました。

完成動画（〜2015/12/29まで公開)
http://fast-uploader.com/file/7004356161098/


# 作りたいもの

今回使うiBeaconは、電源供給が始まると自動で信号を発し始めるもの。
https://www.aplix.co.jp/product/mybeacon/mb001ac/

そのため、自分がiBeaconを持って徐々に部屋に近づいていき、
その信号をRaspberry Piで受けて、
部屋に入った距離になったら（電波強度が強くなったら）
RaspberryPiに繋いだスピーカーから、
ファミマの入店音を鳴らします。

![スクリーンショット 2015-11-29 19.53.03.png](https://qiita-image-store.s3.amazonaws.com/0/60109/1aaa7111-29fd-63b5-c624-6744023a1a4f.png)


![スクリーンショット 2015-11-29 19.56.10.png](https://qiita-image-store.s3.amazonaws.com/0/60109/7744f673-f8df-1e1f-2597-b51c15d50eee.png)




# 今回使用した技術要素

- Raspberry Pi （買ったばっかり）
- Node.js (はじめてコード見た)
- iBeacon (借り物)

![DSC_0362.jpg](https://qiita-image-store.s3.amazonaws.com/0/60109/b7781318-3742-bed0-a40b-24462a1cf853.jpeg)


# 準備物

Raspberry Piのセットアップまでは、
下記に別記事として記載しました。

Raspberry PiデビューしてMinecraft Pi Editionで遊んだ話
http://qiita.com/rina0521/items/b235a08f4d66864f5865

今回用に買ったり借りたもの

- Bluetoothアダプタ(PLANEX)
　https://www.planex.co.jp/products/bt-micro4/
- iBeacon(Aplix)
　https://www.aplix.co.jp/product/mybeacon/mb001ac/


# iBeaconをRaspberry Piで受信

まず、Raspberry PiにBluetoothアダプタを接続し、
iBeaconを受信できるか、確認してみます。
下記のページを見ながら、BlueZをインストールし、
BluetoothのデバイスをONにするところまで行いました。

Raspberry Pi で iBeacon を試してみよう！
https://www.eyemovic.com/blog_it/4269.php

途中、make installに失敗しましたが、

```
$ sudo make
$ sudo make install
```
で実行し直すことで、できました。

ここで、一旦、iBeaconの信号を検知できるか、テストしてみます。
BlueZのコマンドhcidumpによって、検知できるとのこと。

```
$ sudo hcidump &
$ sudo hcitool lescan
```

こんなかんじで、取れました。

![DSC_0361.jpg](https://qiita-image-store.s3.amazonaws.com/0/60109/de4a7cd4-c22c-86d5-4195-0d32cacb4dd0.jpeg)


参考：hcitoolとhcidumpで確認 | RPD7
http://rpd7.tomolog.info/knowledge/raspberrypi/07_hcitool.html

ただ、このままでは、特定の距離で音を鳴らす、
という実装は、とても大変そうです。


# Raspberry PiにNode.jsとbleaconを入れる

bleaconというのを使えば、とってきたビーコン情報を
Node.jsで処理できるとのこと。

まずは、Raspberry PiにNode.jsをインストールするところから。
今度は下記のページを見ながら、Node.jsをインストールします。

Raspberry PiにnodebrewでNode.jsをインストールする
http://qiita.com/yuyakato/items/a1225154445520dc2db3

続いて、bleaconのインストール
（先ほどのNode.jsインストールと同じ人の記事です。多謝！）

Raspberry PiでiBeaconを受信する（Node.js + bleacon）
http://qiita.com/yuyakato/items/739443960fac2668f4a3


# SSHでRaspberryPiに接続

さて、サンプルコードを実行するぞ！
というところで、お気づきかもしれませんが、
上記の手順を、テレビ画面でそのまま実行していました。。。
完全に、SSHの存在を忘れていました。ハイ。

家のMacとRaspberry Piは、同じ無線LANに繋がっているので、
SSHでRaspberry Piに繋ぎます。

raspberry piでコマンドラインを開き
```
$ ifconfig
```
で、wlan0のIPアドレスを確認し、
Raspberry PiのIPアドレスを確認

Macのコマンドラインから、下記コマンドで、SSH接続

```
$ ssh pi@[wlan0のIPアドレス]

The authenticity of host 'XXX.XXX.XXX.XXX' can't be established.
RSA key fingerprint is 57:fc:3e:b3:5e:c8:87:0a:96:a2:6c:3f:31:fb:29:43.
Are you sure you want to continue connecting (yes/no)? yes
```

yesを入力

```
Warning: Permanently added 'XXX.XXX.XXX.XXX'' (RSA) to the list of known hosts.
pi@1XXX.XXX.XXX.XXX''s password:
```

Raspberry Piのパスワードを入力

```
Linux raspberrypi 3.18.11+ #781 PREEMPT Tue Apr 21 18:02:18 BST 2015 armv6l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sun Nov  8 05:46:40 2015
pi@raspberrypi ~ $
```

いけました。Raspberry Piは、
デフォルトでSSH接続可能なのですね。

# Node.jsでiBeacon信号をとる

先ほどのページのサンプルコードを実行します

Raspberry PiでiBeaconを受信する（Node.js + bleacon）
http://qiita.com/yuyakato/items/739443960fac2668f4a3

が、rootじゃないとダメだよと言われエラー。

しかし、
```
$ sudo node スクリプト名
```
では、nodeの場所がわからないと言われる。
sudo実行ではパスが通ってない？
下記の記事を見て、secure_pathをコメントアウト。

sudo時にPATHを引き継ぐ方法
http://qiita.com/akito1986/items/e9ca48cfcd56fdbf4c9d

これで、
```
$ sudo node スクリプト名
```
で、実行できました。


# ファミマの入店音を鳴らす

ファミマの入店音素材は、下記からダウンロード。

タグ検索: ファミマ入店音 - ニコニ・コモンズ
http://commons.nicovideo.jp/search/tag/ファミマ入店音

サンプルスクリプトを流しながら、部屋の中と外を往復すること数回。

部屋の中と外の区切りは、だいたいRSSIが
-75ぐらいのところであることが判明。

せっかくなので、ゴリ押しで作ったコードを公開します。

```catch_beacon_famima.js
var Bleacon = require("bleacon");
var exec = require('child_process').exec,
    child;

Bleacon.startScanning('<自分のiBeaconのID>');
Bleacon.on("discover", function(bleacon) {
  console.dir(bleacon.rssi);
  if(bleacon.rssi > -75){
    child = exec('aplay nc52356.wav')
    process.exit();
  }
});
```
参考：Node.jsで同期的にコマンドを実行できるようにする execsyncs を作った。
http://yosuke-furukawa.hatenablog.com/entry/2014/07/26/145814

精度をあげるためには、本当は、rssiの値の平均をとったり、
離れたことを検知したりしないといけないのですが、
~~手を抜いて、~~取得した値をそのまま評価し、
一度音が鳴ると自動的にスクリプトを停止してます。

そして、これを実行したのが、冒頭の動画です。
**ファミマ気分が味わえますね！！**

2016/12/10追記
私のような出オチコードではなく、
ファミマの入店音を鳴らすアプリを
beacon近接判定も入れて作られた方が
githubにコード公開されておりました！
勉強させていただきました！

iBeacon発信器が、PCに近づくとファミマの入店音が鳴る
https://github.com/nyoro/famima