14
Python BLE (Bluetooth Low Energy) 2016年9月15日 西本卓也 @24motz 広島版 IoT 縛りの勉強会 Vol.3 http://ja.nishimotz.com/iotlt_hiroshima https://github.com/nishimotz/BluefruitLE_samples 1

160915 iotlt-nishimoto-v1

Embed Size (px)

Citation preview

Pythonで BLE(BluetoothLowEnergy)

2016年9月15日

西本卓也 @24motz

広島版 IoT縛りの勉強会 Vol.3http://ja.nishimotz.com/iotlt_hiroshima

https://github.com/nishimotz/BluefruitLE_samples

1

CR2032ボタン電池

• 230mAh,3Vで 6ヶ月 =BLEのユースケース

• http://rbs.ta36.com/?p=20398

2

GenericAccessProfile

• Peripheral=デバイス(ITAG)• Central=デバイスと接続するアプリ(Python)

• Broadcaster=ビーコン• Observer=ビーコン受信アプリ

3

KeyFinder+リモコン機能

• ITAGを紛失するとスマートフォンが警告• スマートフォンを紛失するとITAGが警告• ITAGのボタンを押すと• 位置情報を記録• ダブルクリックでボイスレコーダー実行

• アプリ iTracing →更新されていない• 互換アプリはある(Androidのみ確認)

• いつの間にか静かに接続が切れていたり• 夜中に突然警告が鳴ったり

4

ITAGの中身

5

状態遷移モデル

6

スタンバイ

アドバタイズ

スレーブ

LED点滅

電源オフ

3秒押し

5秒押し

ボタン押しを送信

警告を受信

警告(LED点滅とブザー)

切断

ボタン押し

ボタン押し

接続

警告停止

Centralの状態遷移モデル

7

スタンバイ

デバイスの一覧を取得

スキャン

イニシエイト

マスター

特定のデバイスに接続要求

スレーブの機能を利用(このまま数ヶ月でも)

LightBlue forMac

• BLEデバイスのリストが見える• スタンバイ→スキャン→スタンバイ状態

•機器を選ぶと Service,Characteristicが見える• イニシエイト→マスター状態• GATT=Generic Attribute Profile

• 16進数(GUID/UUID)で指定• ベース部分は共通

• BATTERY SERVICE =180f• 0000180f-0000-1000-8000-00805f9b34fb

8

ITAGで確認できること

• 180f=BATTERYSERVICE• 2a19=BATTERYLEVEL

• 0x64=100

• 1802=IMMEDIATEALERTSERVICE• 2a06=ALERTLEVEL

• 0x02を書き込むと警告• 0x00で停止

• ffe0=未定義Service• ffe1=未定義Characteristics

• subscribeするとボタン押しで 0x01が notifyされる

9

BluefruitLE PythonLibrary

• Adafruitが公開• MacとLinux(RaspberryPi)に対応• LinuxPyBluez• Core BluetoothPyObjC

• Adafruitのデバイスで使う例しかない•やってみたら ITAGを叩ける

10

メインループ

importAdafruit_BluefruitLE,uuidBATTERY_SERVICE=uuid.UUID('0000180f-…)BATTERY_LEVEL=uuid.UUID('00002a19-…')

def main():#デバイスのスキャン、接続、値の読み書き

provider=Adafruit_BluefruitLE.get_provider()provider.initialize()provider.run_mainloop_with(main)

11

デバイスのスキャン

adapter=provider.get_default_adapter()adapter.power_on()

adapter.start_scan()device=provider.find_device()adapter.stop_scan()

print(device.name)

12

接続して値の読み取り

device.connect()

device.discover([BATTERY_SERVICE],[BATTERY_LEVEL])service=device.find_service(BATTERY_SERVICE)c=service.find_characteristic(BATTERY_LEVEL)v=c.read_value()print(ord(v[0]))

device.disconnect()

13

書き込み:write_value()通知待ち:start_notify()

まとめ

• IMMEDIATE_ALERTは helloworld• Bluefruit LEPythonは Central専用• データ収集• Peripheralの調査やデバッグ• RasPiを Centralとして運用

• MacでPythonが独自ビルド版の場合は• pipinstallpyobjc

• リファレンスがないのでソースを読んで理解• スマートフォンアプリ開発

14