Quantcast
Viewing all articles
Browse latest Browse all 8691

最近のNode.jsでBLEのアドバタイジングパケットを補足してみる

はじめに

nobleが虫の息というか、もう息の根を止めてあげていい状態なので他に移行しなければならない。さて次は何がいいだろうかと調べてみてラズパイ用途で行き当たるのは以下の2つくらいじゃないだろうか。

node-ble
node-bluez

node-bleが開発が活発に見えるが、node-bluezもシンプルでよさげ。両方やってみることにする。試した環境はこちら

uname-a
Linux raspberrypi.local 5.8.0-1016-raspi #19-Ubuntu SMP PREEMPT Tue Feb 9 20:12:43 UTC 2021 aarch64 aarch64 aarch64 GNU/Linux

前準備

node-bluzが依存するライブラリとnode.jsをインストールする

sudo apt install-y libglib2.0-dev libdbus-1-dev
sudo apt install-y nodejs npm

ここで入るnodeのバージョンは12.xで古い。nで最新を入れる

sudo npm i -g n
sudo n latest
sudo apt remove --purge nodejs
sudo apt autoremove

/usr/local/binにlatest versionが入るのでパスを通しておく

~/.profile
export"$HOME/usr/local/bin:$PATH"
source ~/.profile
node -v
v15.13.0

TypeScriptの準備

mkdir-p work &&cd$_
npm init -f
npm i -S typescript ts-node bluez node-ble sleep-promise
npx tsc --init

Promiseまわりのエラー回避で tsconfig.jsonのlibを以下にする

tsconfig.json
lib:["ES2015","dom"],

node-bleでやってみた

node-ble.ts
import{createBluetooth}from'node-ble';importsleepfrom'sleep-promise';constmain=async()=>{const{bluetooth,destroy}:any=createBluetooth();constadapter:any=awaitbluetooth.defaultAdapter();if(!awaitadapter.isDiscovering()){console.log('Discovering:');awaitadapter.startDiscovery();while(true){constdevices:any=awaitadapter.devices();console.log(devices);awaitsleep(3000);}}};main();

実行する

npx ts-node node-ble.ts 
Discovering:
[ '4E:2E:8E:F1:63:91', 'E1:A6:93:4A:ED:C3' ]
[ '4E:2E:8E:F1:63:91', '5B:A0:F3:EB:BB:0D', 'E1:A6:93:4A:ED:C3' ]
[ '4E:2E:8E:F1:63:91', '5B:A0:F3:EB:BB:0D' ]
[ '4E:2E:8E:F1:63:91', '5B:A0:F3:EB:BB:0D' ]
[ '4E:2E:8E:F1:63:91', '5B:A0:F3:EB:BB:0D', 'E1:A6:93:4A:ED:C3' ]
[ '4E:2E:8E:F1:63:91', '5B:A0:F3:EB:BB:0D', 'E1:A6:93:4A:ED:C3' ]

とれた。Adapterにイベントハンドラがないので Adapter.device()を一定時間ループで回してとる手法。nobleでイベントドリブンな取得に慣れていたのでこれ思いつかなくてしばらくハマった。一回device()しただけじゃ絶対とれないし。これはこれでコールバックじゃない分制御の汎用性は高いと思うけど。好みの問題だろうか。

node-bluezでやってみた

node-bluez.ts
importBluezfrom'bluez';constbluetooth=newBluez();consthandleOn=async(address:string,props:any)=>{console.log(`[NEW] Device: ${address}, ${JSON.stringify(props.Name)}`);constdev=awaitbluetooth.getDevice(address);dev.on("PropertiesChanged",(props)=>{console.log(`[CHG] Device: ${address}, ${props}`);});};constmain=async()=>{try{bluetooth.on('device',handleOn);awaitbluetooth.init();constadapter=awaitbluetooth.getAdapter();awaitadapter.StartDiscovery();console.log("Discovering");}catch(e){thrownewError(e);}}main();

実行する

npx ts-node node-bluez.ts 
Discovering
[NEW] Device: 54:AB:0C:6F:15:E6, undefined
[NEW] Device: E1:A6:93:4A:ED:C3, "tkr"[NEW] Device: D1:1C:63:61:E0:01, undefined
[NEW] Device: E1:A6:93:4A:ED:C3, "tkr"[NEW] Device: FB:33:A1:32:7F:75, "tkr"[NEW] Device: E1:A6:93:4A:ED:C3, "tkr"

とれた。こちらはAdaptorにイベントハンドラがあって受信したタイミングでパケットが降ってくる。tkrは財布とかに入れてある忘れ物防止タグのTrackRだ。

おわりに

どちらもざっくりコードをみるかぎりDbus APIのラッパーな感じ。アドバタイジングとるだけならイベントドリブンなnode-bluezのほうが好み。ケースバイケースで使っていこうと思う。やっとnobleの葬式ができそう。


Viewing all articles
Browse latest Browse all 8691

Trending Articles