公式のサンプルなどがコールバック地獄で結構辛いので、util.promisify()を使ってなんとかできないかと思うのですが、そこまで上手くはいかないです。
bluebirdのpromisifyAllを使うといい感じに出来ました。
npm i bluebird
'use strict';
const noble = require('noble');
const Promise = require('bluebird'); //Promisifyで利用
const peripheralUUID = 'xxxxxxxxxxxxxxx'; //各自書き換え
const serviceUUIDs = ['180d']; //各自書き換え
const characteristicUUIDs = ['2a39']; //各自書き換え
//discovered BLE device
const discovered = async (peripheral) => {
// if(peripheral.advertisement.localName !== 'Heart Rate') return;
if(peripheral.uuid !== peripheralUUID) return;
noble.stopScanning(); //スキャン停止
console.log(`[Found Device] ${peripheral.advertisement.localName}(${peripheral.uuid}) RSSI${peripheral.rssi}`);
/**
* ペリフェラルへのアクセス
*/
const p = Promise.promisifyAll(peripheral); //Promisify
await p.connectAsync();
console.log(`[Connect Device] coneccting service & characteristic......`);
/**
* サービス&キャラクタリスティックへのアクセス
*/
const services = await p.discoverSomeServicesAndCharacteristicsAsync(serviceUUIDs,characteristicUUIDs);
const characteristic = services.reduce((pre, current) => (current.uuid === serviceUUIDs[0]))
.characteristics
.reduce((pre, current) => (current.uuid === characteristicUUIDs[0]));
const c = Promise.promisifyAll(characteristic); //Promisify
console.log(`[Connect characteristic] coneccting characteristic's Data......`);
/**
* キャラクタリスティックのデータにアクセス
*/
const toggle = async () => {
try {
const data = await c.readAsync();
let state = data.readUInt8(0);
console.log(state);
state = (state === 0) ? 1 : 0;
await c.writeAsync(new Buffer.from([state]), true);
setTimeout(() => toggle(), 1000); //1秒ごとに実行
} catch (error) {
console.log(error);
}
}
toggle();
}
//BLE scan start
const scanStart = () => {
if(noble.state !== 'poweredOn'){
noble.on('stateChange', scanStart)
}else{
noble.startScanning();
noble.on('discover', discovered); //Discover
}
}
scanStart();