2020年6月19日金曜日

Raspberry pi4でBLE ScanのPythonプログラムを作成する

目的

Raspberry Pi 4を用いて、BleAdvertiseのScanを行うまで

見つけた問題点

hcitool lescanを用いるようだが、
コマンドを実施すると、下記のエラーが出た

$ sudo hcitool lescan
Set scan parameters failed: Input/output error
Scanning for BLE devices on Raspberry Pi 4 Model Bを参照すると、
解決方法でデバイスのdown/upをするとあるが、投稿者同等直らなかった

ライブラリとPythonスクリプト

おそらく下記はやらなくてもいいが、上を解決しようと試行錯誤した後。。
Raspberry Pi4はデフォルトではbluezは5.50 (2020/06/19時点)

$ bluetoothctl version
Version 5.50

bluezのアップデート

BlueZ 5.54に置き換える

$ wget http://www.kernel.org/pub/linux/bluetooth/bluez-5.54.tar.xz
$ tar xvf bluez-5.54.tar.xz
$ cd bluez-5.54
$ ./configure --prefix=/usr --mandir=/usr/share/man  --sysconfdir=/etc --localstatedir=/var
$ make
$ make install
一応再起動した方が良い?

バージョンの確認とお試しとしてtestフォルダにあるble advertiseを実行してみる

$ bluetoothctl version
Version 5.54
$ python3 example-advertisement
example-advertisement:201: PyGIDeprecationWarning: GObject.MainLoop is deprecated; use GLib.MainLoop instead
  mainloop = GObject.MainLoop()
Advertising forever...
GetAll
returning props
Advertisement registered

他の端末(例としてMac上のXcode付属のBluetooth Explorerから見ると以下のように出る

Manufacturer Data : {length = 7, bytes = 0xffff0001020304}
kCBAdvDataChannel : 37
Service UUIDs : (
    "Heart Rate",
    Battery
)
Service Data : {
    9999 = {length = 5, bytes = 0x0001020304};
}
Local Name : TestAdvertisement
kCBAdvDataIsConnectable : 0

C言語などや他のライブラリが使うことを考えて
BlueZ 5.50のdev用ヘッダファイルたちを5.54に置き換えておく
バックアップも取っておく

$ sudo cp -ipr lib/ /usr/include/bluetooth.5.54
$ cd /usr/include
$ sudo mv bluetooth bluetooth.5.50
$ sudo ln -s bluetooth.5.54/ bluetooth

bluepyのインストール

bluepyを参照
なお、本ライブラリはルート権限が必要 (デバイスの操作がルートのみ)

$cat ble_rpi.py
from bluepy import btle
scanner = btle.Scanner(0)
devices = scanner.scan(3.0)
for device in devices:
    print("Macアドレス:" + device.addr)
    print("アドレスタイプ:" + device.addrType)
    print("RSSI:" + str(device.rssi))
    print("アドバタイシングデータ:")
    for adTypeCode, description, valueText in device.getScanData():
        print(" " + description + ":" + valueText)
$ sudo python3 ble_rpi.py
Macアドレス:2f:05:xx:xx:xx:xx
アドレスタイプ:random
RSSI:-47
アドバタイシングデータ:
    Flags:1a
    Complete 16b Services:0000fd6f-0000-1000-8000-00805f9b34fb
    16b Service Data:6ffd341691188f76e34f8635f1177c1cadaf86eb405f
Macアドレス:4d:xx:xx:xx:xx:xx
アドレスタイプ:random
RSSI:-52
アドバタイシングデータ:
    Flags:1a
    Tx Power:0c
    Manufacturer:4c001005021cf71772

という感じで表示される。

参考ページ