RaspberryPi + 人感センサー + Sesame でオートロック解除

# 前提・背景
* ここ数年、自宅をスマートホーム化していて、こんなものを導入しています。
    * NatureRemo
        * 赤外線でデバイスとコントロールできます
        * エアコン、テレビ、シーリングを操作できます
    * SwitchBot
        * スイッチのON/OFFをコントロールできます
        * オートロックの解除と風呂の湯張りに使っています
    * Sesame
        * 玄関の鍵の施錠/解錠ができます
    * Google Home + Alexa
        * 上記のデバイスを音声でコントロールできるようになります
        * なんとなくGoogle Home miniを集めていたら7台になってしまいました。
* 今回、玄関の鍵の解錠を自動化しようと考えました。

# やりたいこと
* 鍵の解錠を人感センサーとSesameを使って自動化する
    * 玄関に人が近づく
    * 人感センサーがRaspberryPiに知らせる
    * RasbperryPiがSesameAPIに解錠要求する
    * Sesameが玄関の鍵を解錠する

# 用意したもの
* 人感センサー(HC-SR501)
* RasbperryPi Zero WH
* ジャンパピン(メス-メス)
* モバイルバッテリー
* USBケーブル

# HC-SR501ってこんなやつ
![IMG20191211233719.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9700/965c5a1a-e940-2be2-df86-6c405dd7f9e6.jpeg)

* 激安人感センサーです
* Amazonで5個1000円でした
* https://www.amazon.co.jp/gp/product/B07FDXWLS6/

# RasbperryPi ZeroWHってこんなやつ
![IMG20191211233659.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9700/f3eaed5d-1e25-7379-82fa-6a5321dffc49.jpeg)

* 超小型マイコンです
* Linuxとか動きます
* ヘッダピンがついていて電子回路と連携ができます

# RaspberryPiと人感センサーの接続
* 回路図
![rpi_to_hc_scr01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9700/7db1746b-09fb-ab6c-072f-95c0e272eff8.png)
* 実際につないだのがこんな感じ
![IMG20191211233645.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9700/b24fb292-ca6f-c144-7aa0-64b920ac5b8d.jpeg)

* このあたりを見てつなぎました
 * https://qiita.com/kazuppp/items/dc8170d11aa185e9b233
* LEDとかつけるとわかりやすいのですが、純粋に出力をRaspberryPiで受け付けるだけ
* このやり方だと、メスtoメスのジャンパワイヤだけ用意すればよいです

# 人がいることを検知してSesameに解錠要求する
* Pythonのコードを書きます
* 以下のようなコードを書きました
* べたべた書きすぎですみません
 
```python:sensor_to_sesame.py
# coding: utf-8
import RPi.GPIO as GPIO
import time
import urllib.request
import json

PIN = 14

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

try:
    print ('-----Start-----')
    while True:
        if GPIO.input(PIN) == GPIO.HIGH:
            count += 1
            print("検知しています "+"{}".format(count) + "回目")
            if count == 5:
                print("解錠します")
                url = 'https://api.candyhouse.co/public/sesame/{device_id}'
                data = { 'command': 'unlock' }
                headers = {
                    'Authorization': '{API_KEY}',
                    'Content-Type': 'application/json',
                }
                req = urllib.request.Request(url, json.dumps(data).encode(), headers)
                with urllib.request.urlopen(req) as res:
                    body = res.read()
                time.sleep(10)
                count = 0
            time.sleep(1)
        else:
            print("検知していません")
            count = 0
            time.sleep(3)
except KeyboardInterrupt:
    print("Cancel")
finally:
    GPIO.cleanup()
    print("-----end-----")
```

# ちょっとした解説
* 人がいることを検知する仕組み
    * 人感センサーは検知していないときは0を、検知しているときは1を送ってきます
    * そしてたまに誤検知するので、単純に1がきたら解錠とはできません
    * 今回は検知状態が5秒続いたときに解錠しに行くようにしました
* Sesameに解錠要求する
    * SesameAPIというWebAPIが公開されているので、それを使用しています
    * 詳細はこちら https://qiita.com/mizutoki79/items/63413a977a9f64344587

# 課題
- レスポンスの悪さ
    - SesamiAPIにリクエストを送って実際に解錠されるまでに最大5秒くらいかかります
        - 早い時と遅いときの差が激しいです。
    - 人感センサーが検知する時間も足すと最大10秒くらいかかる計算になります
    - さっさと鍵を開けてほしいのに10秒待機するのはつらいです

# 参考にした記事、サイト
* https://qiita.com/mizutoki79/items/63413a977a9f64344587
* https://qiita.com/hoto17296/items/8fcf55cc6cd823a18217
* https://qiita.com/kazuppp/items/dc8170d11aa185e9b233