【Raspberry Pi】人感センサーが感知したらtimestampをFirebase Realtime Databaseに格納する

#はじめに
この記事は全4章からなる記事の第3章です。

1. [IoTを駆使してお年寄りの家を見守る「だけじゃない」システムを作った【SORACOM Summer Challenge 2020】](https://qiita.com/tik26/items/fab2d34eb3a533fa19a5) 
2. [LTE-M Buttonが押されたらLINE BotへPushメッセージを送る【SORACOM】](https://qiita.com/tik26/items/a3c2e587b7df51313135) 
3. [【Raspberry Pi】人感センサーが感知したらtimestampをFirebase Realtime Databaseに格納する](https://qiita.com/tik26/items/92738ded6bb180cd56d4) :arrow_backward: 今ココ
4. [SORACOMと家電とLINE Botを連携させる【Python / Flask / Raspberry Pi】](https://qiita.com/tik26/items/c0395ee548793159a402) **全ソース公開** 

# きっかけ
人感センサーが反応した時刻や1時間以内に反応した回数をLINE Botに通知したい。ローカルでSQLを動かしてもいいが、人感センサーを取り付けたラズパイとLINE Botのサーバとして使っているラズパイが別々なのでクラウドデータベースに格納したほうが楽なのではないかと思い、定番のFirebaseを使用。

# ラズパイと人感センサーを繋ぐ
### 使ったもの
- Raspberry Pi 3 Model A+(これより上位のものならOK)
- 人感センサーモジュール
- ジャンパーワイヤー（メス-メス）

人感センサーは[こちらのメーカ](https://www.vstone.co.jp/robotshop/index.php?main_page=product_info&products_id=4361)のものを使いました。
![人感センサー](https://www.vstone.co.jp/robotshop/images/4571398312342.jpg)

### 接続
[【Raspberry Pi】自作人感センサーの使い方と活用法](https://chasuke.com/motionsensor/)をそのまま使わせてもらいました。
GPIOの接続間違いには気を付けてください（私は12番ピンとGroundを間違えて動かないというミスをしでかしました）。

#Firebase
[[python] Firebase Realtime Databaseのはじめ方](https://qiita.com/sai-san/items/24dbee74c5744033c330)を参考しさせていただきました。

### パッケージのインストール
以下のコマンドでラズパイにfirebase-adminをインストールします

```
$ pip install firebase-admin
```

### Databaseの作成とルールの変更
FirebaseのコンソールからDatabaseを作成します。`Cloud Firestore`と`Realtime Database`がありますが、今回は**`Realtime Database`**なので注意してください。
ルールを以下のように変更します。
※ テスト用ですので実際に運用する場合は適切なルール設定をしてください
<img src="https://docs.google.com/drawings/d/e/2PACX-1vR6Z2mRhZrrCwowHMszNlVxLGaLfw-zrm6pzzIjL32Bobp1PbbgwkcUO5NHW--PkXA0HurWv17n6n8e/pub?w=906&amp;h=682">

また、「プロジェクトの概要」の右側にある歯車から`プロジェクトを設定 > サービスアカウント > Firebase Admin SDK`に移動し、`Python`を選択してコピー、また`新しい秘密鍵の生成`をクリックして、ダウンロードした秘密鍵をラズパイに保存します。

<img src="https://docs.google.com/drawings/d/e/2PACX-1vRxO-uLoIVIhA-3n0NyDtziHNc4EqZ-9vtC_aSxXcFutKV0aCBPWI0fA5QpbjYGgVEMwHWYobcqKGuH/pub?w=853&amp;h=437">

###人感センサーとDatabaseの連携
以下がコードです

```firebase.py
import firebase_admin
from firebase_admin import credentials
from firebase_admin import db
from datetime import datetime
import time
import RPi.GPIO as GPIO

cred = credentials.Certificate("<ダウンロードした秘密鍵>.json")
firebase_admin.initialize_app(cred, {
    'databaseURL': 'https://<databaseURL>.firebaseio.com/'
})

ref = db.reference('data')

INTERVAL = 3
SLEEPTIME = 20
GPIO_PIN = 18

GPIO.setmode(GPIO.BCM)
GPIO.setup(GPIO_PIN, GPIO.IN)

while True:
    if(GPIO.input(GPIO_PIN) == GPIO.HIGH):
        print(datetime.now().strftime('%Y/%m/%d %H:%M:%S'))
        new_data_ref = ref.push()
        new_data_ref.set({
            'timestamp': {'.sv': 'timestamp'}
        })
        time.sleep(SLEEPTIME)
    else:
        print(GPIO.input(GPIO_PIN))
        time.sleep(INTERVAL)
```

感知したらDatabaseにtimestampとともにPushします。Pushすることで一意のIDが生成されます。どうやらそのIDも時系列みたいです。
#### timestampの登録について
[こちらのIssue](https://github.com/firebase/firebase-admin-python/issues/284)でもありますが、Pythonのfirebase-adminモジュールからタイムスタンプを登録するには一癖あるみたいなので、上記の`'timestamp': {'.sv': 'timestamp'}`のところが参考になれば幸いです。

### デモンストレーション
このように、検知するとRealtime Databaseに書き込まれます。
<img src="https://docs.google.com/drawings/d/e/2PACX-1vRTFv12lbPXyfGtz2rCgjCJy_dvon9cXTj_yzL1uAnNx41Pgy0SJo9_iActeXQ_XDbJCJhv68AWfZmE/pub?w=1042&amp;h=541">

UNIX時間の`1597307961996`は2020/08/13 17:39:21なので完璧ですね。

#まとめ
以上、人感センサーの反応時刻をFirebase Realtime Databaseに格納するまででした。
次はそのデータを別のラズパイから取得します。