Raspberry pi でセンサメダルのデータを受信する

#環境
- 機種：RaspberryPi Zero W
- OS：RASPBIAN STREACH WITH DESKTOP
- カーネルバージョン：4.9
- 言語：Python 2.7.13
- RaspberryPi2 + RASPBIAN JESSIE + bluetoothドングルでも動作しました

#モノ
- センサメダル（ http://www.rohm.co.jp/web/japan/sensor-medal-support ）

#使用するライブラリ
- bluepy

#参考にしたサイト
- 手順1　http://qiita.com/yujimny/items/7e92f240f48550585500
- 手順2　http://tomosoft.jp/design/?p=8104

#前置き
ロームのセンサメダルのデータを`RasupberryPi ZERO W` + `python`で受信したいと思い、調べてみたところ `bluez` というのが見つかったが`gattlib`がインストールできなかった為(ラズパイゼロはメモリ不足で失敗するらしい？)、`bluepy`というものを使用した。

#手順

##1.センサメダルとの通信確認
　ポイント：`0x0b07`に`0100`を書き込むとデータが流れてくるようになる。

###1-1.センサメダルの電源を入れる
###1-2.ターミナルを開いて`sudo hcitool lescan`を実行
対象のアドレスがわかる


```
pi@raspberrypi:~ $ sudo hcitool lescan
LE Scan ...
E3:B0:C8:8F:A1:22 ROHM RAW
E3:B0:C8:8F:A1:22 (unknown)
```

###1-3.`gatttool -b XX:XX:XX:XX:XX:XX -t random -I`　を実行（XX:XX:XX:XX:XX:XXにはセンサメダルのアドレスが入る）

```
pi@raspberrypi:~ $ gatttool -b E3:B0:C8:8F:A1:22 -t random -I
[E3:B0:C8:8F:A1:22][LE]>
```

###1-4.`connect`と打ち、`Enter` →センサメダルに接続する

```
[E3:B0:C8:8F:A1:22][LE]> connect
Attempting to connect to E3:B0:C8:8F:A1:22
Connection successful
```

###1-5.`primary`と打ち、`Enter` 　→サービス一覧が表示される

```
[E3:B0:C8:8F:A1:22][LE]> primary
attr handle: 0x0001, end grp handle: 0x0005 uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle: 0x0010, end grp handle: 0x0012 uuid: 00001801-0000-1000-8000-00805f9b34fb
attr handle: 0x0020, end grp handle: 0x0032 uuid: 0000180a-0000-1000-8000-00805f9b34fb
attr handle: 0x0b00, end grp handle: 0x0b0a uuid: 0179bbc0-0000-0100-8000-00805f9b34fb
```
###1-6.サービスのUUIDを見つける(iphoneやmacのアプリで事前に調べておく)
今回は一番下の行が対象のサービス

###1-7.`char-desc 0x0b00`　と打ち、`Enter` →キャラクタリスティックがザーッとでてくる

```
[E3:B0:C8:8F:A1:22][LE]> char-desc 0x0b00
handle: 0x0b00, uuid: e8340000-e7e5-0000-e7eb-ffffe6ce2800
handle: 0x0b01, uuid: e8340000-e7e5-0000-e7eb-ffffe6ce2803
handle: 0x0b02, uuid: 0179bbc1-0000-0100-8000-00805f9b34fb
handle: 0x0b03, uuid: 0179bbc1-0000-0100-8000-00805f9b2803
handle: 0x0b04, uuid: 0179bbc2-0000-0100-8000-00805f9b34fb
handle: 0x0b05, uuid: 0179bbc2-0000-0100-8000-00805f9b2803
handle: 0x0b06, uuid: 0179bbc3-0000-0100-8000-00805f9b34fb
handle: 0x0b07, uuid: 0179bbc3-0000-0100-8000-00805f9b2902
handle: 0x0b08, uuid: 0179bbc3-0000-0100-8000-00805f9b2803
handle: 0x0b09, uuid: 0179bbc4-0000-0100-8000-00805f9b34fb
handle: 0x0b0a, uuid: 00002902-0000-1000-8000-00805f9b34fb
```

###1-8.notificationのUUIDを見つける
今回は`0x0b06`, `0x0b07`がそう。`0x0b07`に値を書き込むと`0x0b06`からデータが来る。

###1-9.`char-write-req 0x0b07 0100` と打ち、`Enter` →センサメダルのデータが次々と流れてくる

```
[E3:B0:C8:8F:A1:22][LE]> char-write-req 0x0b07 0100
Characteristic value was written successfully
Notification handle = 0x0b06 value: 48 00 cd ff 03 04 39 00 9a 01 5a fb 37 00 7a 00 8b 00 c8 c4 
Notification handle = 0x0b06 value: 47 00 d1 ff 02 04 39 00 9e 01 5a fb 10 00 7a 00 73 00 c8 c4 
Notification handle = 0x0b06 value: 48 00 d0 ff 06 04 37 00 9e 01 5a fb 13 00 62 00 82 00 c7 c4 
Notification handle = 0x0b06 value: 46 00 d2 ff 04 04 3b 00 99 01 5a fb 2f 00 80 00 7e 00 c7 c4 
Notification handle = 0x0b06 value: 47 00 ce ff 0b 04 3b 00 9c 01 59 fb 36 00 77 00 77 00 c6 c4 
Notification handle = 0x0b06 value: 47 00 cd ff 05 04 3c 00 9a 01 59 fb 25 00 7b 00 88 00 c6 c4 
```

###1-10.`char-write-req 0x0b07 0000` と打ち、`Enter` →センサメダルのデータが止まる

```
[E3:B0:C8:8F:A1:22][LE]> char-write-req 0x0b07 0000
Characteristic value was written successfully
[E3:B0:C8:8F:A1:22][LE]>
```

##2.必要なモジュールをインストール

```
sudo apt-get install python-pip libglib2.0-dev
sudo pip install bluepy
```

##3.コードを書いて実行する
`bluepy`を使用して受信したデータを表示するコードを書く。

``` python:medalTest.py
# -*- coding: utf-8 -*-
"""
    2017.09.20 teppei
    ロームのセンサメダルのデータを受信して表示するプログラム
"""

from bluepy.btle import Peripheral
import bluepy.btle as btle
import binascii

# センサメダルのアドレス
ROHM_RAW = "XX:XX:XX:XX:XX:XX"


# データを受信した時に呼ばれるやつ
class MyDelegate(btle.DefaultDelegate):
    def __init__(self, params):
        btle.DefaultDelegate.__init__(self)
    
    def handleNotification(self, cHandle, data): 
        c_data = binascii.b2a_hex(data)
        print c_data

# センサーメダルクラス
class SensorMedal(Peripheral):
    def __init__(self, addr):
        Peripheral.__init__(self, addr, addrType="random")
        

def main():
    # 初期設定
    medal = SensorMedal(ROHM_RAW)
    medal.setDelegate(MyDelegate(btle.DefaultDelegate))
    
    # ノーティフィケーションを有効にする
    medal.writeCharacteristic(0x0b07, "\x01\x00", True)
    
    # データを受信し続ける
    while True:
        if medal.waitForNotifications(1.0):
            continue
        print "wait..."

if __name__ == "__main__":
    main()
```

センサメダルの電源を入れてから python medalTest.pyを実行

```
pi@raspberrypi:~/work/medal $ python medalTest.py 
4d00e9ff02045fff5eff6ffb04004300930060c4
4a00eaff06045fff5dff6dfb26003b009b0060c4
4800e8ff00045eff5eff6dfb01008000ae005fc4
4b00eaff01045cff5eff6dfb1f0060007b005fc4
4a00e7ff030461ff5bff6ffb07004500a7005ec4
4900e9ff05045cff62ff6dfb14007d0077005dc4
```

※受信データはセンサメダルのwebページにある使い方のpdf資料を参考に換算するといいです。