鍵かけ忘れ検知システムを作る

#はじめに
家の鍵をかけ忘れることはあまりないんだけど、不安に陥ることはよくあります。
そこで、家から出た時にかけ忘れを教えてくれたらいいなぁと常々思っていました。
知りたいのは、鍵の傾きなんです。
#やりたいこと
家から出発した時、鍵の状態を確認し、かけ忘れを知らせてくれるシステムを作ります。
#やり方
1.ESP32に加速度センサを接続し、BLEデバイス化して鍵の傾きを確認できるようにしておく。
2.スマホのIFTTTで家から出たとき(exit location)をトリガにRaspberryPiにWebhookする。
3.RaspberryPiはBLE経由で鍵の傾きを取得する。
4.鍵が空いている角度であれば、RaspberryPiはIFTTTにWebRequestを送り、スマホに通知される。
#用意するもの
・ESP-WROOM32(ESP32-DevKitC)
・加速度センサ(ADXL-345)
・Raspberry Pi
・スマホ(IFTTTをインストールしておく)
#完成イメージ
![0DE2F956-0FC3-4350-8E14-FAB0393D5CFF.png](https://qiita-image-store.s3.amazonaws.com/0/140055/09752990-b7f5-beb2-e69b-43357a97a8f2.png)

#作る
##ESP32に加速度センサを接続する
ESP32とI2Cで接続します。
接続は[こちら](https://sites.google.com/a/gclue.jp/fab-zang-docs/ni-yinkiiot/adxl345-i2c)を参考にしました。(Arudinoですが)
![3C06A975-AA00-47FF-A041-4E75285DA9B7.png](https://qiita-image-store.s3.amazonaws.com/0/140055/abe4c4e3-1a44-b3ea-7bf5-85581de96df7.png)
##加速度センサから値を取得する
ソースコードは[adxl345.c](https://github.com/mitazet/esp/blob/master/accelerometer/main/adxl345.c)です。
I2C経由でX軸、Y軸、Z軸の加速度を取得します。
##鍵の状態閾値を確認する
鍵がかかっている状態のセンサ値を取得してみます。
![374E50F9-212B-4FFF-96E8-E2BC980AA0B9.png](https://qiita-image-store.s3.amazonaws.com/0/140055/00626e78-7bd6-376e-0d5d-9032318270d9.png)

次のような値になりました。
![F3B57955-2F9D-489E-BCB6-2FBF3699976D.png](https://qiita-image-store.s3.amazonaws.com/0/140055/928a7308-890b-acd5-41d2-9de3cffda318.png)

鍵が開いている状態のセンサ値を取得してみます。
![D2D47ABB-056D-492D-B5E7-C42684224C5F.png](https://qiita-image-store.s3.amazonaws.com/0/140055/9ce62a53-4184-c23a-a40e-ebb5daa2d272.png)

次のような値になりました。
![905CE512-BFDF-4B49-9A85-3EA0880A36B5.png](https://qiita-image-store.s3.amazonaws.com/0/140055/ffd4ce27-1ac8-4a4c-bbc2-4224ea540d92.png)
この結果から__X軸の値が7以下、Y軸の値が-10以上のとき__に鍵が開いていると判定します。
Z軸の値はあまり変化がなかったので使用しません。
##ESP32をBLEペリフェラルにする
ソースコードは[accelerometer](https://github.com/mitazet/esp/tree/master/accelerometer/main)です。ビルドにはESP-IDFが必要になります。
gatts_accelerometer.cでESP32をGATT Serverにして、READイベント発生時にADXL345の値を取得しています。
コードはESP-IDFに付属しているGATT Serverのサンプルを参考にしています。
UUIDは製品化するわけではないので、適当な値にしています。
##RaspberryPiをBLEセントラルにする
RaspberryPiでBLEを使う準備は[Check! Raspberry Pi で Bluetooth 経由のセンサーデータを取得する 〜 準備編](https://qiita.com/dz_/items/4e858e4d50db19b57491)を参考にしました。
PythonでPyBluezを使用し加速度センサの値を取得しようとしましたが、うまくいかなかったので[bluepy](https://ianharvey.github.io/bluepy-doc/)を使用しました。
ソースコードは[check_door_key.py](https://github.com/mitazet/python_code/blob/master/check_door_key.py)です。
ESP32のMACアドレスに接続してセンサ値を取得します。
確認した閾値を用いて、鍵が開いている場合にIFTTTにWebRequestを送ります。
WebRequestのEvent名は`door_key_opend`にします。KeyはIFTTTのサイトで確認し設定します。

##IFTTTを設定する
まず、家を出た時をトリガにRaspberryPiにWebhookを送るApletを作成します。
This→Location→You exit an areaを選択し、場所を家にします。
<img width="375" alt="B6C10AC0-0448-401E-BB83-14BAE89AAEDD.jpeg" src="https://qiita-image-store.s3.amazonaws.com/0/140055/b98742fd-6a8a-d607-aa74-a4499dcb4811.jpeg">

次にThat→Webhookを選択し、WebRequestの設定を行います。
URLにはRaspberryPiのアドレスを設定します(事前にWebサーバーにしておく必要があります)。
これで最初のAplet作成は完了です。
<img width="375" alt="97BD046F-4E1E-4730-8E88-23FF01A0917B.png" src="https://qiita-image-store.s3.amazonaws.com/0/140055/5f59fd70-5b85-e354-e0d5-bb844da2e5ef.png">

次にRaspberryPiからのWebhookをトリガにスマホに通知を送るApletを作成します。
This→Webhooks→Receive a web requestを選択します。
Eventは「door_key_opened」にします。
<img width="375" alt="A6E15C87-3209-4728-9B6F-EF2C9F833F71.png" src="https://qiita-image-store.s3.amazonaws.com/0/140055/72b82202-7fbb-1f51-7438-5a8c0ff2d721.png">
That→Notificationsを選択し、通知内容を設定します。
<img width="375" alt="58CA7703-F400-4794-8110-927828746184.png" src="https://qiita-image-store.s3.amazonaws.com/0/140055/99e848a0-1ad3-6e00-95c3-544864839e72.png">
これで全てのApletが作成完了です。

##IFTTTからのWebhookを処理する
IFTTTからRaspberryPiにWebhookが来たときはPHPで処理を行います。
JSONのbodyが{“message”: “check door key”}である場合に、上記の鍵状態を確認するスクリプトを実行します。

```php
<?php
function func_check_door_key(){
    exec("sudo python3 /home/pi/python_code/check_door_key.py");
    return;
}

$json_string = file_get_contents('php://input');
echo $json_string;
$array = json_decode($json_string, true);
var_dump($array);

if ($array['message'] == 'check door key'):
    func_check_door_key();
endif;

?>
```

#テスト
現在、家には家族がいるので、鍵をかけ忘れて出かけてみます。
そして...
![A73C871B-60FB-438C-B3D2-771628AD3D39.png](https://qiita-image-store.s3.amazonaws.com/0/140055/8c937818-c431-afc6-92c2-fe6f3b0163e4.png)

おっと忘れてたぜ!!
危ない、危ない。
※IFTTTへWebRequestを送ってから通知が来るまでは割とタイムラグがあるため注意が必要です。
#おわりに
回りくどく色々使っている気もしますが、学習のためですのでご容赦ください。