Node.jsでBLEを扱うパッケージのnobleとnoble-deviceで非公式SDKっぽいものを作ってみる


Node.jsアドベントカレンダー8日目です！昨日はGoのアドベントカレンダーにBLEネタを書きましたが今日はNode.jsです。

##はじめに

先日JavaScriptからFlowerPowerを利用する記事を書きました。

> [JavaScriptから部屋の植物を監視。 Parrot Flower PowerをNode.jsから制御する](http://qiita.com/n0bisuke/items/f50996a60f5472b9c80f)

メーカー側がSDKを公開していなくても、BLEデバイスはBLE制御用の情報さえ分かれば制御することも可能になります。

そこでnobleとnoble-deviceを使ってSDKなどの実装を追ってみようと思います。

## noble

Node.jsからBLEを扱うパッケージ。説明をみるとcentralとして動作します。

https://github.com/sandeepmistry/noble

> 参考: [たった6行!最も簡単にiBeaconの電波を「発信」する方法](http://qiita.com/Morikuma_Works/items/a0dd3cfcd1eef8dbd492)
> 参考: [MacやLinuxでnodeを使ってiBeaconをつくれるとはどういうことなのか？](http://qiita.com/kazuph/items/1302174e9bb52911d371)


## noble-device

nobleをラップして使いやすくしてくれているパッケージ。

https://github.com/sandeepmistry/noble-device


### noble-deviceを内部で利用しているパッケージ

色々なデバイスの非公式SDK的なものがnobleとnoble-deviceを使って作られています。

* [tethercell](https://github.com/sandeepmistry/node-tethercell/)
* [ble-bean](https://github.com/jacobrosenthal/ble-bean)
* [sentortag](https://github.com/sandeepmistry/node-sensortag)
* [Flower Power](https://github.com/sandeepmistry/node-flower-power)

## PlayBulbを使って試してみます。

これらの実装をもとに[PlayBulb Candle](http://amzn.to/1NEMXJy)という電子キャンドルを制御するSDKを作ってみます。

> 参考: [GoからBLE制御でPLAYBULB Candleの操作をしてみる](http://qiita.com/n0bisuke/items/d3966b11b2e9143d6651)


![](https://i.gyazo.com/16ba8b9e79484bd3762d69951cd68e4e.png)

簡略化したいのでとりあえず、`[A]色を変えるメソッド`と`[B]名前を変えるメソッド`を実装してみました。

```playbulb.js
var util = require('util');
var NobleDevice = require('noble-device');

var SERVICE_UUID = 'ff02'; //キャンドル制御自体のService
var COLOR_CHARA_UUID = 'fffc'; //[A]キャンドルの色のCharacteristic
var NAME_CHARA_UUID = 'ffff'; //[B]名前情報のCharacteristic

function PlayBulb(peripheral) {
  NobleDevice.call(this, peripheral);
  this.name = peripheral.advertisement.localName;
}

NobleDevice.Util.inherits(PlayBulb, NobleDevice);
PlayBulb.SCAN_UUIDS = [SERVICE_UUID];
//[A]色を変えるメソッド
PlayBulb.prototype.setColor = function(color, callback) {
  var data = new Buffer('00'+color, 'hex');
  this.writeDataCharacteristic(SERVICE_UUID, COLOR_CHARA_UUID, data, callback);
};
//[B]名前を変えるメソッド
PlayBulb.prototype.setName = function(name, callback) {
  var data = new Buffer(name);
  this.writeDataCharacteristic(SERVICE_UUID, NAME_CHARA_UUID, data, callback);
};

module.exports = PlayBulb;

```

ソースコード中の[A][B]の機能とUUIDは[前回記事](http://qiita.com/n0bisuke/items/d3966b11b2e9143d6651)にも記載しています。

FlowerPowerの実装を真似ています。`setColor`や`setName`というメソッドを作っていて、内部で`writeDataCharacteristic`というメソッドを実行しています。

`writeDataCharacteristic`に **ServiceのUUID**と **使いたい機能のCharacteristicのUUID**、 **入力値**を与えることでBLEデバイスに対して命令を送れます。

センサーなどデータを取得するだけの場合は`readDataCharacteristic`を同じように使うことで値取得ができます。

###使ってみる

`.discover`などのメソッドはnoble側であらかじめ設定されているメソッドです。
コネクション後に`setColor`を呼び出します。

```setColor.js
var PlayBulb = require('./playbulb');

console.log('PLAYBULBを探しています...');
PlayBulb.discover(function(pb){
  console.log('PLAYBULB:'+pb.name+'を見つけました。接続中です...');
  pb.connectAndSetup(function(err){
    if(err) return;
    console.log('接続しました。');
    //色を変更
    pb.setColor(process.argv[2],function(hoge){
      console.log(hoge);
    });
  });
});
```

```bash
$ node app.js ff0000
```

などにして実行するとキャンドルが赤く光ります。
これも昨日の記事を参考にしてください。

##まとめ
Bluetooth Codeの情報さえ拾うことができれば、勝手SDKっぽいものを作れることがわかりました。
とりあえずPlayBulbはもう少し触ってみたいと思います。

BLE開発できると色々と可能性広がりますね！
nobleやbleno、noble-deviceなどのリポジトリは要チェックです。

それでは :+1: