Google Homeで給湯ポットの気持ちを代弁してみる

# はじめに

社内のコミュニケーションスペースには給湯ポットが置いてあります。コーヒーを飲もうと思い、ドリップバッグをカップにかけ、給湯ボタンを押すとすぐにゴボッ、ゴボゴボッ...（ほぼ空だった）。しょんぼりしながら給水する悲壮感。あぁ、これはなんとかしたい。

水を補充するモチベーションって何でしょう...。感謝かな。やっぱり、感謝されたら嬉しいよね。ついでに「お湯を入れに来たら湯沸かし中だった」問題も回避できるようにしよう。

# やりたいこと

- 水を入れて湯沸かしがかかったら「給水していただき、ありがとうございます」などと発話する。
- 発話内容は複数候補からランダムに選択する。
- 湯沸かしに合わせて「湯沸かしを開始/終了しました」とSlackへ通知する。

# どうなったか

発話はこんな感じになりました。（途中で、椅子に足を引っかけた音が...）

[![movie.png](https://qiita-image-store.s3.amazonaws.com/0/60193/fcbd2799-156b-2119-9a84-b077463236bd.png
)](https://drive.google.com/open?id=1ANYo6OsotePmmdk3dKn_nmxy-E0MaUTe)
※動画が始まらない場合は[こちら](https://drive.google.com/open?id=1ANYo6OsotePmmdk3dKn_nmxy-E0MaUTe)から... :confounded:

設置してまだ数日しか経っていませんが、心なしか、満水近くの給湯ポットに出会うことが多くなった気がしています。（親バカフィルター越し）

ただ、すぐに飽きられてしまうのは目に見えているので、少しずつでも改良していかないと...。[^1]

[^1]: 「今日は気分が良いので記念撮影をしましょう。それではいきますよ～。3・2・1（カシャ）」イベントを不定期に発動させて、給水してくれた方の写真を撮り、画像認識して「xxさんが給水してくれました」とSlackへ投稿するとか。Pepperくん、入社してください。

# どうやったか

給湯ポットのあるコミュニケーションスペースに、なんと[MESH](http://meshprj.com/jp/)一式が転がっていたので、[GPIOタグ](http://meshprj.com/jp/tag/MESH-100GP-GPIO.html)を使ってみることにしました。

## 処理フロー

給湯ポットに交流電流センサを取り付け、その出力電圧をGPIOタグで監視しました。MESHレシピを挟み、発話はIFTTT→Firebase→Ubuntu→Google Home、Slack通知はMESH SDK→Slackとしました。

![flow.png](https://qiita-image-store.s3.amazonaws.com/0/60193/e72d95c8-8b3d-98df-2ac4-f39ad53d24ce.png)

途中のMESHレシピは以下のようになりました。

![recipe.png](https://qiita-image-store.s3.amazonaws.com/0/60193/65c63fac-6877-d956-a0e6-216586fae279.png)

## 給湯ポットの湯沸かし監視

[平均値整流型電流変換回路](http://www.u-rd.com/technical/kairo1.html)を組み、[クランプ式交流電流センサ（CTL-10-CLS）](http://www.u-rd.com/products/CTL-10-CLS.html)の出力を変換してGPIOタグへ繋げました。GPIOタグの入力上限である3Vに調整できるよう、半固定抵抗を挟みました。

![circuit.png](https://qiita-image-store.s3.amazonaws.com/0/60193/83f031eb-ac3a-35ef-c8b8-657430570275.png)

MESHレシピでは「しきい値2Vを上回る」「0.5Vを下回る」をトリガーとしました。

![gpio.png](https://qiita-image-store.s3.amazonaws.com/0/60193/5c1d58e7-948e-3968-e982-95479af1e944.png)

変換回路の作成にあたっては、[多機能電力計の製作](http://www.asahi-net.or.jp/~SE1M-NITU/html/Power_Meter.htm)、[mbedによる自宅の電力消費量測定](http://lute.penne.jp/thumbunder/?p=784)を参考にさせていただきました。何から手を付けたらよいか分からず、[暗くなると自動点滅するLEDキャンドル](http://amzn.asia/d/1j5Y0Ku)を購入してアワアワするレベルの電子回路:beginner:でも達成できました。ありがとうございます。

## Google Homeでの発話

発話内容は、FirebaseのDatabaseを経由して、Google Homeで読み上げさせました。処理フローのIFTTT→Firebase→Ubuntu→Google Homeのうち、Firebase～Google Homeは[以前の記事](https://qiita.com/hideo-works/items/db25a748889d47d5eff2)で[紹介した処理](https://qiita.com/hideo-works/items/db25a748889d47d5eff2#raspberry-pi)とほぼ同じ（差異はOSだけ）ですので、ここではIFTTT→Firebaseのみを記載します。

### [IFTTT](https://ifttt.com/)

読み上げ要求がかかったことを、IFTTTを利用して、Firebaseへ通知します。

#### this

thisとしてMESHの「Event from MESH app received」を指定します。

![mesh.png](https://qiita-image-store.s3.amazonaws.com/0/60193/a3a53b43-4ac8-7ea7-7fca-a082032b01de.png)

#### that

thatではWebhooksを利用します。

FirebaseのDatabaseは以下のような構成にしています。wordの値として「announce 発話内容」と書き込むと、その更新イベントが下位フローでフックされ、Google Homeが読み上げます。

```
プロジェクト名-xxxxx
 └ googlehome
 　 └ word: ""
```

そのためWebhooksは以下のように指定しました。

![Webhooks.png](https://qiita-image-store.s3.amazonaws.com/0/60193/dece3607-1e59-375c-ae94-8b148f1ae07a.png)

MESHレシピでは、GPIOタグからの出力を「ランダムに切替える」スイッチを経由して複数のIFTTTへ繋げ、それぞれで読み上げさせたい内容を指定しました。例えばこんな感じ。

![ifttt.png](https://qiita-image-store.s3.amazonaws.com/0/60193/f20add56-42c2-db68-08f2-b5656eaf14f6.png)

イベントIDは前項の「Event from MESH app received」で指定したものとそろえます。

## 湯沸かし状況のSlack通知

MESH SDKを利用して「給湯ポット」タグを作成し、Slackへの通知を行いました。

### [MESH SDK](https://meshprj.com/sdk/doc/ja/)

![tag.png](https://qiita-image-store.s3.amazonaws.com/0/60193/2b59e1c0-095c-c860-d4a8-0f7869c4cf0f.png)

開始/終了の入力コネクタを用意し、受け取ったコネクタに応じたメッセージをSlackへ通知します。通知するメッセージは、MESHレシピの設定から変更できるよう、プロパティとしました。

![function.png](https://qiita-image-store.s3.amazonaws.com/0/60193/a660b89d-7bea-e8ff-c1f5-63db25ac0b43.png)

ファンクションの各メソッドは以下のように実装しました。Slackへの通知では[Slack API](https://api.slack.com/methods)を利用しました。

```js:Initialize
return {
  runtimeValues : { messageText : '' }
};
```

```js:Receive
var messageText = '';
switch ( index ) {
  case 0:
    messageText = properties.startMessage;
    break;
  case 1:
    messageText = properties.endMessage;
    break;
}
runtimeValues.messageText = messageText;

return {
  runtimeValues : runtimeValues,
  resultType : 'continue'
};
```

```js:Execute
var url = 'https://slack.com/api/chat.postMessage';
var data = {
  token : 'xxxx-xxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx', //HubotのAPI Token
  channel : '#thermo-pot', //チャンネル名
  text : runtimeValues.messageText,
  as_user : true
};

ajax( {
  url : url,
  data : data,
  type : 'post',
  timeout : 5000,
  success : function ( contents ) {
    log( 'Thermo-Pot: Success' );
    callbackSuccess( {
      resultType : 'continue'
    } );
  },
  error : function ( request, errorMessage ) {
    log( 'Thermo-Pot: Network error' );
    callbackSuccess( {
      resultType : 'continue'
    } );
  }
} );

return {
  resultType : 'pause'
};
```

Resultメソッドは利用しませんでした。

# おわりに

Slackを確認すると...、

![slack.png](https://qiita-image-store.s3.amazonaws.com/0/60193/56a59e91-9685-694e-f8cd-7921aca87214.png)

うぁぁぁー、めっちゃ感謝されてたー。どうやら湯沸かしがかかった後は、数分ごとに「停止」→「すぐに再開」が繰り返されるようで...。まずはここから改良しないとー。

**（追記）**
圧倒的感謝っ...！問題は、電圧が下がってから、一定時間のうちに電圧が上がった場合を「何もなかった」（湯沸かしの終了/開始は発生していない）と判断することで回避できました。

# あとがき

作っていて思ったのですが、電流センサの出力を監視すると「利用された」ことが分かる、つまり「そこに人がいる」ことが把握できます。これって、人とつながりを持てるきっかけになりそうな気がしています。回路を組む必要のない製品（[変換器一体型の交流電流センサ（CTT-CLS-CV）](http://www.u-rd.com/products/CTT-CLS-CV.html)）もあるようですので、いろいろなところで活用できたらなと思っています。