Google Homeでトイレセンサー作ってみた

Google Homeでトイレセンサーを作ってみました。
トイレが空いたらGoogle Homeが自発的に教えてくれます。

![IMG_0389.JPG](https://qiita-image-store.s3.amazonaws.com/0/154355/b7e532d6-2303-ec3a-27ca-a2e9f048b2ee.jpeg)

#はじめに
会社には男性トイレの個室が１つしかありません。
急激にお腹痛くなってトイレに行ったけれど、既に誰か入っていて我慢する苦行を強いられていました。
そこで、トイレが空いたことを教えてくれればわざわざトイレまで見に行かずに済むのではないかと考えました。

#処理の流れ
![構成図.001.png](https://qiita-image-store.s3.amazonaws.com/0/154355/f67c3da2-3d84-a730-be7b-1a9e7fe11073.png)

#デモ動画
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">トイレが空いたことをGoogle Homeが教えてくれます。<a href="https://twitter.com/hashtag/GoogleHome?src=hash&amp;ref_src=twsrc%5Etfw">#GoogleHome</a> <a href="https://twitter.com/hashtag/Firebase?src=hash&amp;ref_src=twsrc%5Etfw">#Firebase</a> <a href="https://twitter.com/hashtag/RaspberryPi?src=hash&amp;ref_src=twsrc%5Etfw">#RaspberryPi</a> <a href="https://twitter.com/hashtag/IoT?src=hash&amp;ref_src=twsrc%5Etfw">#IoT</a> <a href="https://t.co/fsUE5l8Oe3">pic.twitter.com/fsUE5l8Oe3</a></p>&mdash; がおまる@HoloLens研究者 (@gaomar) <a href="https://twitter.com/gaomar/status/943366193963966465?ref_src=twsrc%5Etfw">2017年12月20日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

#環境
* Google Home
* Raspberry Pi Zero W
* [ESPr Door Sensor](http://ssci.to/2741)
* [firebase-arduino](https://github.com/firebase/firebase-arduino)

#ドアの開閉状況を知る
ドアの開閉状況はESPr Door Sensorを使います。
下記のように磁石に反応して開閉状況を知ることが出来ます。
Wi-Fiが内蔵されているので、単体でネット環境に繋がります。

![2741-7.JPG](https://qiita-image-store.s3.amazonaws.com/0/154355/19105205-345c-8cd9-f92d-43676366d0bd.jpeg)

###Firebase設定
Firebaseの設定は[コチラ](https://qiita.com/h-takauma/items/54e968268afeaadbd6b4#firebase%E3%81%AE%E8%A8%AD%E5%AE%9A)を確認してください。

![スクリーンショット_2017-12-20_14_39_02.png](https://qiita-image-store.s3.amazonaws.com/0/154355/e31535e9-7e6a-861a-d648-80149a44843c.png)

###ESPr Door SensorからFirebaseへ開閉状態を知らせる
ArduinoからFirebaseを更新するためのライブラリをダウンロードします。
[firebase-arduino](https://github.com/firebase/firebase-arduino)

```c:スケッチ.ino
#include <ESP8266WiFi.h>
#include <FirebaseArduino.h>

extern "C" {
  #include "user_interface.h"
}

#define CLOSE 0
const char* ssid     = "接続するWi-FiのSSIDを指定してください";
const char* password = "xxxxxxxxxxx";

#define FIREBASE_HOST "xxxxxxxxxxx.firebaseio.com"
#define FIREBASE_AUTH "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

WiFiClient client;

boolean flag = false;
int reed_sw = 5;

void setup() {
  Serial.begin(115200);
  delay(10);

  // We start by connecting to a WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, password);
  WiFi.mode(WIFI_STA); // omajinai
  
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(250);
  }

  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  pinMode(reed_sw,INPUT);

  // Firebase初期化.
  Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);

}

int value = 0;

void loop() {
  int door_state;
  door_state = digitalRead(reed_sw);

  Serial.print("Door State:");

  // ドアの状態(0: Close、1:Open)
  if(door_state == CLOSE){
    Serial.println("Close");

    // FirebaseにCloseを書き込みます
    Firebase.setString("toilet/word", "Close");
    
    if (Firebase.failed()) {
      Serial.print("setting /number failed:");
      Serial.println(Firebase.error());  
      return;
    }
  }
  else{
   Serial.println("Open");
   
   // FirebaseにOpenを書き込みます 
   Firebase.setString("toilet/word", "Open");

   if (Firebase.failed()) {
      Serial.print("setting /number failed:");
      Serial.println(Firebase.error());  
      return;
    }
  }

  if(door_state == CLOSE){
    ESP.deepSleep(0, WAKE_RF_DEFAULT);         //ドアが閉じている間はドアが開くまで待機
  }
  else{
    ESP.deepSleep(0, WAKE_RF_DEFAULT);        //ドアが開いている間はドアが閉じるまで待機
  }
  delay(1000);
  
}
```

###FirebaseのFIREBASE_AUTHを確認する
上記のスケッチの途中にある`FIREBASE_AUTH`はコチラから確認出来ます。

![スクリーンショット_2017-12-20_14_51_09.png](https://qiita-image-store.s3.amazonaws.com/0/154355/07272344-82cb-7325-dd65-1b8359d870cc.png)

###動作確認する
これでマイコンボードに書き込んで動作を確認してみましょう。
うまく動作していればOpen／CloseがFirebaseに書き込まれます。

![スクリーンショット_2017-12-20_15_00_38.png](https://qiita-image-store.s3.amazonaws.com/0/154355/2654c8b1-2e75-dfb5-6643-964f70f07b86.png)

#Google Homeに開閉状態をしゃべらせる
ここからGoogle Homeの設定を行います。
[google-home-notifier](https://github.com/noelportugal/google-home-notifier)をラズパイに適用しておきましょう。

インストール方法は下記を参照してください。
https://qiita.com/SatoTakumi/items/c9de7ff27e5b70508066

###Firebaseが更新されたらしゃべらせる
ラズパイにFirebaseをインストールしておきましょう。
これでOpen／Close状態を取得してGoogle Homeがしゃべってくれます。

```javascript:app.js
// モジュール読み込み
var firebase = require("firebase");
var googlehome = require('./google-home-notifier');

var deviceName = 'お好きな名前';
var ip = '192.168.xx.xx'; //ここにIPを記載
var language = 'ja';

// Google Home設定
googlehome.ip(ip, language);
googlehome.device(deviceName,language);

// firebase設定
var config = {
  apiKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  authDomain: "xxxxxxxxxxxxx.firebaseapp.com",
  databaseURL: "https://xxxxxxxxxxxx.firebaseio.com",
  projectId: "xxxxxxxxxxxxxx",
  storageBucket: "xxxxxxxxxxxx.appspot.com",
  messagingSenderId: "xxxxxxxxxxxxx"
};
firebase.initializeApp(config);


try {
    //database更新時
    var db = firebase.database();
    
    db.ref("/toilet").on("value", function(changedSnapshot) {
    
        //値取得
        var value = changedSnapshot.child("word").val();
        
        if (value == "Open") {
            googlehome.notify("トイレが空きました", function(notifyRes) {

            });
        } else if (value == "Close") {
            googlehome.notify("トイレが空いてません", function(notifyRes) {

            });
        }
    });
} catch (err) {
    console.log(err);
}
```

#まとめ
サクッと作ることが出来ました。Firebaseはとても便利ですよね^^
ドアの開閉状況が分かるので、トイレだけでなく違う用途にも使うことが出来ると思います。
違うセンサーと組み合わせて状況に応じてGoogle Homeがしゃべるって事も可能ですね。