Wio NodeのSDKをNode.jsで書いてみた

※この記事は [IoTLT Advent Calendar](http://qiita.com/advent-calendar/2016/iotlt) 2日目の記事です。

WebSocket対応しました！=>[ [Wio Node SDKをWebSocket対応した](http://qiita.com/heppoko_dev/items/45f9aefc77c83d7bf016) ]

### 概要
[Wio Node](https://www.seeedstudio.com/Wio-Node-p-2637.html)を簡単に扱えるようにSDKをnode.jsで書いてみました。
リポジトリ: https://github.com/fuku2015/wio_node

### Wio Node とは
センサーを繋いでWi-Fiと接続するだけで、API経由で値を取得・変更できるモジュールです。

* ESP8266を搭載しており、Wi-Fiドングル不要
* コネクタを繋ぐだけで[Groveセンサー](http://qiita.com/shu223/items/0fe5a932ea52aa7a2c94)を簡単に接続
  * 2つまで接続可能
* Wi-Fi接続はスマホアプリから簡単設定
* OTAでファームウェアアップデート・APIを自動生成
  * サンプルのCurlが表示されるので利用も簡単
  * アプリ上でAPIリクエストのテストが可能
* WebSocketで値が変わったら検知することも可能
    * こちらもサンプルコードをアプリ上で実行可能

と、試すだけなら半田付けレス/コーディングレスでかなりとっつきやすいものとなっています。
ハード初心者だけどとりあえず何かセンサーデータを使ってみたいという方に特にオススメです。
(初めて触った時の自分がそうだったので。)

値段も1000円程度と安く、[スイッチサイエンス](https://www.switch-science.com/catalog/2799/)や[dotstudio](https://dotstud.io/projects/wionode-social-remote-control/![image](https://qiita-image-store.s3.amazonaws.com/0/79789/5db974e6-8f83-f192-b80c-01764ea1fbb2.png)
)で購入できます。

![image](https://qiita-image-store.s3.amazonaws.com/0/79789/c8f40fba-ae60-b1e5-6482-74afe0bed4c9.png)
画像引用元：https://dotstud.io/projects/wionode-social-remote-control/

### Wio Node SDK (本題/書いたもの)
ただ、実際に活用するとなると、一々URL組んだりトークン付けたりレスポンス加工するのは意外と面倒だったりします。
せっかく簡単にセンサーデータを扱えるモジュールなので、コード側でももっと簡単に使えるようにできないかということで、SDKを書いてみました。
(あんまりちゃんと調べてないので、既にあったらごめんなさい。)

リポジトリ: https://github.com/fuku2015/wio_node

言語はNode.jsです。
選定理由は自分が一番使うので書きやすかったというだけで、他意はありませんよ。
いやホントに。

#### 使い方
##### インストール
今のところnpm公開はしていないので、`git clone`で取得してきます。

```
$ git clone https://github.com/fuku2015/wio_node.git
$ cd wio_node
$ npm install
```
##### イニシャライズ
モジュールを`require`して、インスタンスを生成します。

```
const Wio = require("path/to/repository/lib/wio_node");
const wio = new Wio("YOUR_ACCESS_TOKEN");
```
`YOUR_ACCESS_TOKEN`は、アプリのサンプルリクエストの末尾についている`access_token=`の後の文字列です。

```
// 例
https://us.wio.seeed.io/v1/node/GenericDOutD1/onoff_status?access_token=ここの文字列
```

##### GenericDIn
GenericDigitalInputを利用できます。

```
const dIn = new wio.GenericDIn();

// センサーの値を取得
dIn.fetch()
.then((res)=>{
  console.log(res); //return {onoff: 0/1}
})
.catch((err)=>{
  // Error handling
  console.log(err);
});
```
##### GenericDOut
GenericDigitalOutputを利用できます。

```
const dOut = new wio.GenericDOut();

// センサーの値を取得
dOut.fetch()
.then((res)=>{
  console.log(res); //return {onoff: 0/1}
})
.catch((err)=>{
  console.log(err);
});

// センサーの値を入力した値に変更　
dOut.send(val); // input 0 or 1

// センサーの値を1(high)に変更　
dOut.on();

// センサーの値を0(low)に変更　
dOut.off();

// センサーの値を、入力したミリ秒間だけ1(high)に変更　
dOut.sendHighPulse(ms);

// センサーの値を、入力したミリ秒間だけ0(low)に変更　
dOut.sendLowPulse(ms);
```
Pulse系のメソッドは、元の値に関わらず終了後にミリ秒間変更したのと反対の値になります。

##### その他
レスポンスはコールバックとプロミスの両方で受けられます。

```
// Promise
dIn.fetch()
.then((res)=>{
  console.log(res); //return {onoff: 0/1}
})
.catch((err)=>{
  // Error handling
  console.log(err);
});

// Callback
dIn.fetch((err, res)=>{
  if(err) // Error handling
  console.log(res);
});
```

どちらのポートのセンサを操作するかをインスタンス作成時に指定することができます。

```
// ポート番号0でインスタンス生成
const dOut = new wio.GenericDOut(0);

// ポート番号1でインスタンス生成
const dOut = new wio.GenericDOut(1);

// ポート番号0でインスタンス生成(デフォルト値)
const dOut = new wio.GenericDOut();
```
ポート番号はWio Nodeの印字で確認できるほか、APIのURLからも確認できます。
以下の例だと、`GenericDOutD`の後ろの1がセンサーの番号となります。

```
https://us.wio.seeed.io/v1/node/GenericDOutD1/onoff_status?access_token=ACCESS_TOKEN
```

### Future Work
* WebSocket対応
* test書く
* (需要があれば)npm公開
* 対応センサー拡充 or カスタム用クラスの追加
  * とりあえずGenericAIn/Out?

センサーの入力が変わったら検知できるのは需要がある(自分が使いたい)ので早めに実装予定。
npm公開するかどうかは反応みて考えます。
(そもそも非公式なので、勝手に出していいのか的な話もあったり。)

あとはアプリで対応しているすべてのセンサーに対応するのは辛いので、自分でカスタムして使えるようなクラスを用意するといいのかなーとか考えてます。

### 感想
ADD(Advent Calendar駆動開発)で数ヶ月ぶりに個人のコードを書きましたが、やってみるとやっぱり楽しいですね。
~~FBにイイネしたら無茶振りしてきた~~二日目の枠を用意してくれた@n0bisukeさんに感謝w
ただ、もう少し整えてから出したかった気もするので、しばらく継続してやっていこうと思います。
(Validationとか全然書いてないので、入力値にはお気をつけください…。)

自分もそこまでWio Nodeを活用してモノづくりしてないので、もっとこうした方が使いやすいといったご意見や、このセンサー対応してほしいなどあれば、コメントいただけると嬉しいです！
あと、もちろんp-rもお待ちしています！

明日はカンボジア人(でしたっけ？)の@shanonimさんです。