JavaScript だけで BLE に入門する
この記事はCPS Lab Advent Calenderの2日目の記事です。1日目の記事はM5Stackをメトロノームにするです。3日目の記事は
@kotako_rs です。
書くネタが全くなかったので、研究で気になっていたBLEについて調べて実装してみました!
やってみたこと
ChromeからBLEデバイスに接続し、そのデバイスの電池残量をWebページに表示してみます。
今回はRaspberry Pi 3とMacを接続しています。
ハードウェアの知識はほとんどないですが、JavaScriptのみ書いて実現することができます!すごい
BLEについて
通常のBluetoothより省コストで通信を行うことができる技術です。 既存のBluetooth同様2.4GHzの電波を用いていますが、通信速度・通信範囲・データサイズ等がとても小さいものです。(実際には10kbps、10m、33bytesくらい?らしい?)
下の記事が個人的に分かりやすくて参考になりました。他にも良い記事があったら教えて下さい。
- Bluetooth がコンパクトになった
- GAP、 GATTという共通仕様を用いる
- サーバー・クライアントみたいにセントラル・ペリフェラルという存在がある
- Characteristic がBLEのデータを持つ単位で、Service がそれらをまとめる
- Advertise, Scan, Connect, Disconnect という通信の流れ
- 単方向通信もあるみたい
というくらいの、フワッとした理解です...。正直まだ全然理解できていません。
bleno
BLEペリフェラルを実装するための、nodejsライブラリです。
電池残量を取得するサンプルをRaspberry Pi で動かして、後ほどブラウザから見つけてもらいます。
電池残量のようにどういった形式のデータを扱うか、というのがGATTプロファイルで、battery-serviceが公式が提供しているGATTプロファイルの1つです。独自に定義することもできます。
以下のサンプルコードをRaspberry Pi 3 に保存して、
bleno/examples/battery-service at master · noble/bleno · GitHub
自分の環境がはそのままだと動かなかったので、依存関係に手を入れます。
Bluetooth-hci-socket という依存ライブラリが古いので、他の方が修正してくれたものに向き先を変えてあげます。参考issue
// package.json ... }, "resolution": { "bleno/bluetooth-hci-socket": "https://github.com/jrobeson/node-bluetooth-hci-socket/#fix-builds-for-node-10" } }
BLEの仕様がなんとなく分かると、コードもなんとなく読めると思います。
Web Bluetooth API
ブラウザでBluetoothを利用するためのAPIです。
現在策定中ですが、試験機能としてChrome で利用できます。chromium ベースだからか Opera でも利用できるんですね。
Can I use... Support tables for HTML5, CSS3, etc
利用したい場合は、試験機能を有効にするために chrome://flags/#enable-experimental-web-platform-features
を有効にする必要があります。
The first version of this specification allows web pages, running on a UA in the Central role, to connect to GATT Servers over either a BR/EDR or LE connection.
と書いてあり、GATTプロファイルを用いてBluetoothデバイスと通信するためのものという事が分かります。
セントラルとして動作します(Web Bluetooth APIを用いてデバイスを見つけて接続する)
またセキュリティから、localhost か https のページでしか使用することはできません。試験機能がoffかhttpかBluetooth機能がない場合は navigator.bluetooth
でnullが返されるので、そこでチェックしておきます。
同様にデバイスへの接続も勝手にする事はできず、ユーザーが選択する必要があります。
PCは上記gifのように、Android Chromeでは以下のようなモーダルが出てきました。
以下チュートリアルを確認しながら、先程作成したRaspberry Piを探して接続するコードを書いていきます。
developers.google.com
デバイスを検索するモーダルを出して接続し、電池残量を取得するまでが以下になります。
パッと見やる気が失せますが、これだけです!
connect() { // Web Bluetooth APIが使用できるか if (!navigator.bluetooth) return; // battery_serviceを持つデバイスを検索して、データを取得するまで navigator.bluetooth .requestDevice({ filters: [{ services: ["battery_service"] }] }) .then(device => device.gatt.connect()) .then(server => server.getPrimaryService("battery_service")) .then(service => service.getCharacteristic("battery_level")) .then(characteristic => characteristic.readValue()) .catch(e => console.log(e)); }
以下、create-react-app したものを修正してこのコードを入れたものです。
Raspberry Piのサンプルを準備して実行すると出てきました!👀
まとめ
間違っているところなどあればご指摘お願いします!
だらだらと書いてしまいましたが、JavaScript だけ書いてBluetoothデバイスとそれを利用するアプリを作る事ができました!
身の回りのBLEデバイスや研究室にあるマイコンを使って、なんだか面白いモノが作れるんじゃないかなとワクワクしますね👨💻(思いついてないですが)
ハード開発に縁の薄い自分でも、 JavaScript のみで開発ができると手が出しやすく嬉しいです。
では、研究は全く進んでいませんが、奄美大島に行ってきます。