BLEを知る・触る・動かす

以前、BLEを使ったIoT案件に携わったことがありました。そこでは、協力企業側でBLEの送受信する基盤とモジュールを用意してもらって、それをアプリに組み込む作業だったので、BLEの送受信のコアに関して、iOSとAndroidでどういう実装をしているのかまでは追うことができませんでした。
今回は、そんなBLEを知って、触って、動かすことを東京八耐でやったのでざっとまとめました。

## BLEを知る

### BLE: Bluetooth Low Energy
いろんなサイトにはBLEを使って何するかを基準に話されているので、規格や仕様などはWikiで確認した。
Wiki: https://ja.wikipedia.org/wiki/Bluetooth_Low_Energy

#### 特徴・できること
Wikiなどでわかったことは、次の内容でした。

- 「ブロードキャスト」と「コネクション」の2つの送受信ができる。
- 「省エネルギーであること」「複雑でないこと」「低コストであること」である。
- 通信速度の規格値は、約10kbps(MAX: 1Mbps)である。
- 到達距離は、約5メートル(MAX: 30メートル)である。
- Beaconの送受信には、識別IDをBeaconデバイスとアプリに設定しなければならない。
  - Bluetoothの仕様: https://www.bluetooth.com/ja-jp/specifications/assigned-numbers/service-discovery
  - Beaconとは？: http://iot-jp.com/iotsummary/iottech/bluetooth/beacon%E3%81%A8%E3%81%AF%EF%BC%9F/.html
- etc...

そのため、すでに世に出ているBLEを用いた通信システムがどういった仕様なのか参考にして、目標・目的を決めていこうと考えました。

### Eddystone
GoogleがOSS化しているBLEプロジェクト。Chrome/iOS/Androidで実装できるようにサポートしており、Eddystoneの仕様に合わせて作られたBeaconデバイスも販売されている。

ソースコード: [GitHub](https://github.com/google/eddystone)

#### 特徴・できること
Eddystoneには、次の3つの機能を持っている。

- Eddystone-UID
  - Eddystone-UIDフレームは、10バイトの名前空間と6バイトのインスタンスで構成された不透明でユニークな16バイトのビーコンIDをブロードキャストします。
  - 詳細: https://github.com/google/eddystone/tree/master/eddystone-uid
- Eddystone-URL
  - Eddystone-URLフレームは、制限された広告パケット内にもっと収まるように、圧縮されたエンコード形式を使用してURLをブロードキャストします。
  - 詳細: https://github.com/google/eddystone/tree/master/eddystone-url
- Eddystone-TLM
  - Eddystone-TLMフレームは、Beaconのバッテリ電圧や温度などのBeaconデバイスの状態や持っている情報をブロードキャストします。
  - 詳細: https://github.com/google/eddystone/tree/master/eddystone-tlm

### BLE for Unity
GoogleがOSSで出しているEddystoneは、Chrome/Android/iOSで同じようにBLEが扱えると謳っているので、これをUnityや他の開発ツールにプラグインとして扱えないかを最初考えました。

#### Asset Store
すでにUnityでBLEを扱えるプラグインがストアに出ている。
次の3つがよく目に入るプラグインである。

- Bluetooth LE for iOS, tvOS and Android - $20.00
  - https://www.assetstore.unity3d.com/en/#!/content/26661
- iBeacon - $35.00
  - https://www.assetstore.unity3d.com/en/#!/content/15260
- Estimote Unity - $30.00
  - https://www.assetstore.unity3d.com/en/#!/content/79776

## BLEを触る・動かす

### 目標・目的
[去年のLINE DEVELOPER DAYでもらったLINE Beaconのデバイス](https://engineering.linecorp.com/ja/blog/detail/117)を放置していたので、これを使って何かできないかと考えていました。
**LINE Beaconのデバイスから発信したBeaconをEddystoneを組み込んだアプリで受信する**ところを見たいと思い、多分できるだろうと思って[八耐](https://atnd.org/events/89658)で作ろうとしました。

### 準備したこと
- テスト用にBeaconを受信するアプリをストアからDL
- Nodeのbleaconモジュールを使ってテスト用にMacからBeaconを発進させる準備
  - 参考記事: [たった6行!最も簡単にiBeaconの電波を「発信」する方法](http://qiita.com/kpkpkp/items/a0dd3cfcd1eef8dbd492)
- Eddystoneのインストール
- LINE DEVELOPER DAY 2016でもらったLINE Beaconのデバイス

#### テスト用の環境を作る
BeaconをNodeで発信できるbleaconモジュールを起動させて、ストアからDLしたBeaconアプリで受信できるか確認しました。
DLしたアプリ: [ビーコン検知](https://itunes.apple.com/jp/app/dnp-ble%E3%83%93%E3%83%BC%E3%82%B3%E3%83%B3%E6%A4%9C%E7%9F%A5%E3%82%A2%E3%83%97%E3%83%AA/id1076233265)

これで、受信側だけのテストと発信側だけのテストができて、今回の目標の受信側のテストがLINE Beaconのデバイス以外でも確認することができるようになりました。

### やりたかったこと
まずは、以下の段取りで実装していこうと考えました。

- **検証その1**: LINE BeaconのデバイスとEddystoneを連携させる
- **検証その2**: Node.jsを用いたBeaconの発信をEddystoneが受信する

### 結果
「LINE BeaconのデバイスとEddystoneを連携させる」も「bleaconモジュールから発信したBeaconをEddystoneで受信する」も**実現することができませんでした。**
「bleaconモジュールから発信したBeaconをEddystoneで受信する」の場合、Eddystoneの仕様を用いて作られたBeaconデバイスが必要か、Eddystoneで受信できるように発信側(Node側)でBeaconの実装が必要があるとわかりました。

#### 気づいたこと
BLEは、送受信側で同じUUIDを扱う必要がいるため、専用のアプリが必要になります。
Eddystoneで、「専用のアプリケーションを必要とせず、ブラウザのみでビーコンを受信できる」とうたっているものの実際には違う。
Eddystoneは、EddystoneデバイスとChromeアプリまたはEddystoneを組み込んだアプリが必要であり、LINE Beaconのデバイスもまた、LINEアプリとLINE Messaging APIと連携が必須だとわかりました。

やはりBLEを扱っている以上、専用アプリ・デバイスは必要であることは変わりない、ということですね。

### LINE Beaconのデバイスについて間違っていた認識

#### ①LINE BeaconのデバイスとRaspberryは似たデバイス **← ウソ**
LINE Beaconのデバイスは、LINE Messaging APIと連携するために作られたBeaconデバイスである。
そのため、LINE Beaconのデバイスには、他のBeaconデバイスとは異なる仕様で作られている。

詳細: [ラズベリーパイでLINE Beaconのデバイスが作成可能に！「LINE Simple Beacon」仕様を公開しました](https://engineering.linecorp.com/ja/blog/detail/117)

#### ②LINE BeaconのデバイスをBeaconデバイスとしてBeaconアプリと連携ができる **← できない**
LINE Beaconのデバイスは、市販で販売されているBeaconデバイスとは異なるため、ストアなどにアップされているBeaconを受信するアプリでは受信できない。
LINE Beaconのデバイスは、LINEでしか受信できない。

### Eddystoneについて間違っていた認識

#### ①Eddystoneは、モジュールまたはライブラリで提供されている。 **← 違う**
Eddystoneは、BLE技術を用いた規格であって、その規格に沿って作られたソースコードが用意されている。
そのため、ライブラリ・モジュールにしたい場合は、開発者側で作ってメンテナンスしなければならない。

#### ②Eddystoneは、Chrome/Android/iOSで同じ機能が扱えるクロスプラットフォームとして提供されている。 **← 違う**
クロスプラットフォームとは、例えばAndroidとiOSで同じソースコードを扱えてビルドできることを指すが、Eddystoneは、クロスプラットフォームとして動かせるためのコンパイラーなどは存在せず、各プラットフォームの言語ごとに作られているため、クロスプラットフォームの定義には入らない。
Eddystoneは、BLEを簡単に扱えるライブラリーやモジュールになる前のプロジェクト・ソースコードで提供されている。

#### ③Eddystoneは、どのBeaconデバイスでも連携ができる。 **← 連携できないデバイスがある**
Eddystoneの規格に沿って作られたBeaconデバイスでないと受信できない。
公式にも、チュートリアルと一番最初に指定した企業が作ったBeaconデバイスを入手することと書いてあった。

詳細: [Get Started with Beacons](https://developers.google.com/beacons/get-started)
## まとめ
今回は、調査不足でした...。
こーゆーのは、[八耐](https://atnd.org/events/89658)でやってホント良かったと痛感しました笑汗

今回の経験によって、BLEとは何かと今後BLEを用いた開発をする際に、気をつけるべきことがわかったので簡単にまとめました。

### Eddystoneを扱うには制約がいるため、興味本位では採用できない。
Eddystone(Google)がサポートしているBeaconデバイスが必要、または~~受信できるようにEddystoneの仕様に沿ってる発信側を実装する。~~
あとは、[Get Started with Beacons](https://developers.google.com/beacons/get-started)を一通り確認すると、途中から**サーバー・アプリ・Beaconデバイスの連携をGoogle Cloud Platform上で管理することになる**ため、Googleに依存することを考えると、Eddystoneを本当に扱うのか悩みどころですね。。。

といっても、
> Use the Google Beacon Dashboard (recommended).

と定義されており、推奨と書いてあるため扱わなくても問題ないようですが、せっかく管理画面側を用意しているため使った方が得ですね。
個人的には、新規でEddystoneでBLEを組み込んでも影響があまりないプロダクトや既存アプリにクーポンやスタンプラリーなどのその場所限定で動作する規模であれば採用して問題ないかなと感じました。


#### [追記]
あとからちゃんと見ていくと、Eddystoneの発信ツールがAndrodアプリなどで用意されていた。

- [Txeddystone-UID](https://github.com/google/eddystone/tree/master/eddystone-uid/tools/txeddystone-uid)
  - Eddystoneの発信機側、Androidアプリになっている。
     - 参考: [Google発のBeacon用オープンフォーマットEddystoneをAndroidで触ってみた](http://qiita.com/chibatching/items/0cb0eaad42607a4f5754)


### BLEでユーザーに何をさせるのか考える
「**お店にBeaconデバイスを設置してクーポンを配布する**」のか、「**スタンプラリーのようなゲーミング要素でBLEを扱う**」のか、「**とあるBeaconデバイスから受信するとBOTが話しかけてくる**」とかなど、要件によってBLEの実装方法が変わってきます。
この場合は、全てEddystoneですぐに実装できるかもしれませんが、EddystoneがサポートするBeaconデバイスが必要になります。

また、**BLE通信でユーザー同士のコミュニケーションやゲームシステムを作りたい**場合は、送受信の両方をアプリ側に実装し、どちらが送信側で受信側か通信フローの管理が必要だったりと、ゲームシステムと一緒に設計が必要です。

### BLEの送受信を開発する場合は、要件を確定させて仕様を決めてから設計する。
今回の経験を活かして、次にやるべきことを考えたところ、**Eddystoneを参考またはカスタマイズして、独自BLE通信ライブラリを開発する**ことを思いつきました。
Eddystoneは、ライブラリやモジュール単位ではなく、ソースコードで提供しているため、使うと色々と制約があって面倒だと感じてしまったため、BLEシステムを作るお手本として独自でBLE通信を作るか、カスタマイズした方がいいのではと感じました。

おそらく、Beaconデバイスからもアプリ同士でもBLE通信ができた方がアイディアが広がるため、まずは、Eddystoneとそれ以外のBLEを扱っているライブラリやモジュールを調べて、どんな設計をしているのかを理解していこうと思いました。