enebularのflow変数を使って、コーヒータイムにアイドルを

※この記事は「[enebular Advent Calendar 2016](http://qiita.com/advent-calendar/2016/enebular)」12/22の分です。


#はじめに

前回、GCPのAPIを使って、[ポケモン生活を快適にしました](http://qiita.com/k-harada413/items/1be86eb194893ab28a39)。
そして、応用編でアイドルを召喚しました。
さいかわアイドルあのちゃん↓
<img width="248" alt="15.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/1363b6f7-6d70-a117-85f3-afae9bc2cb34.png">
これをweb上のボタン<img width="77" alt="35.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/997b5fc6-e946-0ce8-4068-f86b215a2fdb.png">ではなく、最も癒してほしいタイミングで自動で召喚される、そんなIoTチックなことをWio-Nodeを使って実装しました。

## 成果物
完成系のgif↓
![IMG_7723.GIF](https://qiita-image-store.s3.amazonaws.com/0/132212/2799ad60-a00a-273c-3997-2e6c78323871.gif)
あのちゃんとようなぴがきた！

### どうなってるの？
1. カップの下に光センサがございます。
2. n秒の単位でWio-Nodeが光量データを送信いたします。
3. 光量データを前回値と比較し、カップが持ち上がったことを検出します。
4. **あのちゃんが微笑みます**:v:


めっちゃトイレ行く頻度増えそうですね！！:toilet:

### デバイス側
![IMG_7724.JPG](https://qiita-image-store.s3.amazonaws.com/0/132212/0fd0de91-727f-1096-4838-062e9e0f9a89.jpeg)
これただ頂いたものを繋げて置いてるだけなのでかっこよくどうにかしたいですね。

#レシピ
- 前回のフロー（GCP+SlackBot）
- Wio-Node
- Light Sensor
- 美味しいコーヒー（gifでは水飲んでます）

## [Wio-Node](https://www.switch-science.com/catalog/2799/)とは
小型のwifi対応開発ボードです。
iOS及びAndroidのモバイルアプリで設定が可能なので、プログラミングさっぱりでも開発できちゃう優れものです。
APIの発行もアプリで楽チンですよ。

<img width="320" alt="IMG_7713.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/ea1de50b-ef9f-3c38-b459-4377fec08d30.png">
タップで、それぞれの接続機器をセットして、アップデートするだけ！
画面下部の「View API」からAPIの発行を行うことができます。


先日、弊社で@tseigoさんによるWio-Nodeハンズオンが行われ、参加いたしました！その際はありがとうございました！
（開催概要：[IoTLT番外編！ WioNodeハンズオン at ウフル](https://iotlt.connpass.com/event/45392/)）
（Wio-Nodeとenebularについては@tseigoさんのアドカレ3日目の記事へ：[enebularでデータを取りやすいWio Nodeへのシンプルな取得方法](http://www.1ft-seabass.jp/memo/2016/12/03/enebular-wio-node-simple-flow/)）

## msg変数とflow変数とglobal変数
こっからenebularの話ですが、まずは上記の3つの変数の仕様確認を行いました。

<img width="62" alt="2.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/7e9c7093-12d4-c4ae-df9d-b9921dc1a14e.png">のPropertyを見ると、普段扱う`msg`のほかに`flow`と`global`があります。
<img width="250" alt="1.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/3eb2cbf5-ab9e-ac07-ed64-775ba699138e.png">

どう違うのか、検証用にこんなFlowを組んでみました。
<img width="385" alt="8.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/dea0031e-add2-51c3-c2b2-4a874eeeb1d9.png">
上からmsg, flow, globalの3つに分かれていて、
上のtimestampを押すと`hoge.payload`に値がセットされ、
下のtimestampを押すと`hoge.payload`を`msg.paload`へセットし現在値をログから見れるようになっています。
（下手な日本語なので、検証結果見てもらった方が早いです:poop:）

### msg
<img width="474" alt="3.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/8cdefe6f-20c1-5019-e3af-8e4cb7300bfd.png">
このようにmsgはつながっているnode上でしか保存されない変数ということがわかります。
`msg.payload.hoge`に何かが入っている状態で、`msg.paylod`に値を代入されるとhogeが円環の理に導かれて消えてしまいます:angel:

### flow
<img width="469" alt="6.png" src="https://qiita-image-store.s3.amazonaws.com/0/132212/1f4bddbf-cc7e-de54-847f-44c89ed9537c.png">
flow変数は同一Flowの画面上なら共有されるようです。タブが変わってしまうと値は参照されません。
一次的に値を保存したいときなど、`flow.hoge`に逃がしておくとよさそうです:runner:

### global
<img width="495" alt="7.png" src="https://qiita-image-store.s3.amazonaws.com/0/132212/96248358-fa52-cfd7-5862-586710ac6ffa.png">
global変数は、別のタブでも値が参照できました。
繰り返し使う関数などをglobalに代入しておくと、便利そうですね:bulb:


今回は、光センサを使って**前回取得値との比較**を行ったので、flow変数を用いました。

# 実際のFlow
<img width="490" alt="9.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/3e0791f8-8274-afe6-70e2-8a5efd9eef28.png">
<img width="67" alt="aaaa.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/fa994391-dff7-4a13-d37c-969c595fb434.png">ノードで取得値(msg.payload)をflow変数に逃がしてめっちゃ一時保存しています。

## 前回のおさらい
Flowの下のとこです。（前回詳しく解説していなかったので、少し書きます。）
光センサから受け取る光量を前回取得時の比べ、閾値を超えていたら、画像検索が走ります。
画像検索は「あのちゃん+<img width="75" alt="11.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/1e1473f4-4403-3d99-1a6b-1cd295a22dd8.png">」で行っています。↓中身
<img width="282" alt="10.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/3bd797f8-6a57-d313-c28c-cb5990ba2d05.png">
```"ゆるめるモ！","私服","インスタ","かわいい","悪魔","咲","ようなぴ","けちょん","しふぉん","ほぼほぼ","舌","白い",```
こんな感じの配列をUTF-8に変換して突っ込んでます。
関数走らせれば、直入力でもいけそうなのですが。。
この配列からランダムで一つとってきて、検索してます。

<img width="86" alt="12.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/09f68d14-6a9b-a0be-6295-77ae3e18ac39.png">では、先ほどの配列を`msg.payload`にセットして、
<img width="246" alt="13.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/e1be8a63-41b8-b008-5efd-12786a30273a.png">

<img width="55" alt="14.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/03bc5db8-9538-a6c5-723d-e6dbf083bd16.png">で<img width="56" alt="15.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/587d9bfd-0e32-e124-0882-f2f1f3176feb.png">に渡します。
<img width="356" alt="16.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/183cd477-661f-74bf-51ef-945ce606d9e3.png">

```js
var word = msg.payload.word[Math.random() * msg.payload.word.length | 0];
```
ここで、先ほどの配列から1つのワードだけランダムで引っ張っています。
`url=`のあとですが`'`クオートでも`"`ダブルクオートでもなく、アクサングラーブ（＠の上のやつ、インラインになっちゃってうまく表示できない）を使っています。
そうすると`${hoge}`で変数渡せます～:v:すごい！（こなみ）

## 現在値と前回値を比較する
今回やったとこだけ抜粋したフロー↓
<img width="398" alt="aa.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/8bad96f8-43ee-44c2-41ea-ee48a22b356b.png">

見ての通り、今回の実装で<img width="67" alt="aaaa.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/7c02b3ef-820b-42cb-4dfd-6a841ad3fadb.png">と仲良くなることができました:relaxed:



<img width="66" alt="17.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/e38d14c8-e0de-39b3-a1c8-f6cc423c7b69.png">でWioNodeからの光量データを取得します。
アプリから発行されたURL置いてるだけなので、中身は割愛。

データを<img width="55" alt="14.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/4ae613e6-7b97-47d5-9aa8-d8faf15aef22.png">に変換し、<img width="116" alt="18.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/419b96fb-e95c-aeb9-567d-79d746cbdb78.png">で現在値をとりあえず一時的に逃がします。

<img width="261" alt="19.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/ea79a970-01a8-da61-6f91-6ea869cd6287.png">
こんな感じ。
`msg.before`に前回値が代入されている`flow.before`の値をセット。前回値の保存については後続のフローで行っています。
`msg.payload.analog`に光量データがはいっているので、`msg.latest`に逃がします。


<img width="110" alt="20.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/1d07fa22-b97d-3ac3-7783-ea31e11193ce.png">で、今回一番やりたかった前回値の比較を行っています。

<img width="238" alt="21.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/dfc5ff62-1fd4-cf32-5bbb-8e36af4ce649.png">
先ほどセットした値を計算しているだけですね。

で、閾値を超えているかを<img width="105" alt="22.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/6580c1f8-b0c8-26ed-8142-5e2f21c02fc7.png">で判定しています。
<img width="236" alt="23.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/143cce12-2d1d-d36a-b000-d375145e916c.png">
これで、「あらかじめコーヒーカップが置いてあって、持ち上げたとき」だけ後続のフローに流れるようになります。

これだけで回すとゴミがあってうまく回らなかったので、<img width="96" alt="24.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/cd8961cf-1de8-4e66-8c4f-32d90b5c02a5.png">でズルをしました。
<img width="232" alt="25.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/0473f398-d163-5f1b-bcae-f9138b872ca7.png">
ダミー値を代入しています。後続のフローに影響するものを取り除きました。



<img width="70" alt="26.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/6b517d41-0417-c77c-79f6-e35d13fd3cae.png">で、現在値をflow変数に保存しています。今回の肝ですね。
<img width="252" alt="27.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/18190300-4aa5-192c-1f7b-eeaede61aef2.png">
`flow.start`でスタート時の制御を行っています。
`flow.before`に取得した光量値を代入し、次回取得時との比較に使います。

頭の一発目チェック付近へ参ります。`flow.start`を扱っているところです。
<img width="87" alt="28.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/278b2f3b-58cc-e90b-3cdc-314854788a67.png">で分岐をしています。
<img width="228" alt="29.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/f1ee5109-a0cf-4fec-5a6a-462d35b1eefc.png">

2回以降の取得であれば、ここのフローはスルーして流れます。
1回目の取得の時に前回値が存在しないので、ダミーデータの代入の必要があります。
<img width="53" alt="30.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/28e50673-2cc3-4d20-5ee9-84d876a4babc.png">ここでやってます。
<img width="243" alt="31.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/4fb83725-f5b3-a1b8-1dd3-465645301a98.png">

これがないとうまく回らずで詰まっていました:angel:

#まとめ

前回の[ポケモン生活快適化](http://qiita.com/k-harada413/items/1be86eb194893ab28a39)をしている最中に思いついたものでしたが、自分の構想通りに実装できました。

今までは<img width="56" alt="15.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/b7395b2c-b077-a059-5b63-e673ba40c6bc.png">のようなfunctionノードで値の比較や、代入を行っていましたが、
<img width="67" alt="aaaa.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/2332d3b2-b985-72c7-69e9-7867a731dbf7.png">を使うことにより、ノードの中身を見ずとも、データの流れをデザインしていくことができるので、エラーの特定なども容易にすることができました！:point_up:

「functionを使ったら負け」と以前言われたのですが、その意味が少しわかった気がしました。