ポストに投函されたらお知らせしてくれるデバイスを作ってみた

# 作った背景
　昨年親が亡くなり、親が住んでいた家を管理しなければならなくなりました。
水道・ガスはたまに帰ってみればよいし、電気は電力会社のサービスで遠隔で確認できれば良いものの、地味に困ったのが郵便物。
すぐに対応しなければならない書類が郵送されていたりして、結構確認に行くのが手間でした。（車で片道1時間くらいかかる）
大事な書類が期限付きで届いたりもするので放置するわけにもいかず、とはいえ、行ってみたものの何もなかった時の残念な感じはいただけません。
そんな問題を解決したく、ポストに何か投函されたらお知らせしてくれるものを作りました。

# システム構成
　システム構成は以下のような形です。
![コンテスト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392998/24b09a40-9be4-d6b7-b4ad-18a06af46bc7.png)




普段住んでいない家でもあり、ネットワーク環境を整えるのも手間なのでSORACOMさんのSIMと手元で眠っていたUSBドングル(AK-020)を使いました。
電気は通しているので電源の心配はありません。
SORACOMさんのIoTボタンでも良かったのですが、後々別の用途にも使いたかったのでラズパイを使いました。


# 使った部品
今回のシステムを作るにあたり、用意した部品です。

| 部品名 | 数量 | 説明 |
|:-:|:-:|:-:|
| SORACOM SIM  | 1  | 通信するのに必要です。  |
| AK-020  | 1  | USB通信モジュールです。SORACOMさんから購入  |
| Raspberry Pi 3B+  | 1  | ラズパイ本体です。 https://raspberry-pi.ksyic.com/main/index/pdp.id/435/pdp.open/435 |
| SDカード(8G) | 1  | OSを格納するSDカードです。  |
| USBケーブル(A-microB) | 1  | 電源供給用です。  |
| ACアダプタ | 1  | ダイソーで売っているUSBチャージャーを利用(2.4A出力)  |
| ラズパイのケース | 1  | お好みのものを使えばよいと思います。  ​|
|  モノスティック　ブルー |  1 | IEEE802.15.4でセンサーと通信するためのドングルです。https://akizukidenshi.com/catalog/g/gM-11931/  |
| TWELITE BLUE PAL | 1 | センサー情報を送信するモジュールです。https://akizukidenshi.com/catalog/g/gM-13909/ |
| 開閉センサーパル | 1 | 開閉センサーです。https://akizukidenshi.com/catalog/g/gM-13910/ |
| パル専用ケース | 1 | センサーのケースです。https://akizukidenshi.com/catalog/g/gP-14749/ |
| 電池(CR2032) | 1 | センサー側の電池 |
| 磁石 | 1 | ポストの投函検出用。ダイソーで売っていた超強力磁石を利用 |
| 養生テープ | 適量 | センサーの固定に利用 |

# 作り方
## ハードウエアの準備
- [こちら](https://mono-wireless.com/jp/products/twelite-pal/index.html)の説明を参考にTWELITE BLUE PALと開閉センサーパルを接続し、ケースに組み込みます。（電池もいれる）
- センサーを組み立てたら、磁石とセンサーをポストにいい感じで組付けます。（後で微調整が必要なのでここでは仮止め程度で）（センサーはポスト本体側に、磁石は受け口の蓋につけると良い感じになります）
- Raspberry Piをケースに組付けます。
- AK-020とモノスティックブルーをRaspberry Piに接続します。

## ソフトウェアの準備
### IFTTTの設定
[こちら](https://amg-solution.jp/blog/14267)の記事を参考に、WebHookとLINEの連携を行います。今回、WebHookのイベント名は"post_in"としました。
この時、WebHookで使用するkeyを確認しておいてください。

### Raspberry Piの設定
[こちら](https://soracom.jp/recipes_index/4171/)を参考にAK-020で通信できるところまで設定します。（Napterを使用するかどうかはお好みでどうぞ)
AK-020でインターネット接続ができたら、モノスティックの設定を行います。
以下の内容を`/etc/udev/rules.d`に置きます。置いたら再起動します。

```90-usb.rules
KERNEL=="ttyUSB*", ATTRS{../idVendor}=="0403",ATTRS{../idProduct}=="6001",SYMLINK+="ttyUSB-Zigbee"
```

再起動し、/dev/ttyUSB-Zigbeeというファイルが見つかればOKです。

次に必要なパッケージを追加でインストールします。

```shell:
sudo apt install python3-pip
sudo pip3 install pyserial
```

次に以下のソースコードを/home/pi以下に置きます。

```python:post_check.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import requests
import serial

IFTTT_Key = "IFTTTのWebHookのKeyを入れる"

# IFTTT_Webhook
def ifttt_webhook(eventid):
    # payloadには適当に値を入れておく。
    payload = {"value1": "Internet",
                "value2": "Of",
                "value3": "Things" }
    url = "https://maker.ifttt.com/trigger/" + eventid + "/with/key/" + IFTTT_Key
    response = requests.get(url)
    print(response)


def loop():
    posted_flag = False

    ser = serial.Serial("/dev/ttyUSB-Zigbee", 115200)

    while True:
        state = ser.readline()
        print( state )

        print(state[64])

        if state[64] == 0x30: # Open状態の場合
            if posted_flag == False:
                # IFTTT_Webhook
                ifttt_webhook("post_in")
                posted_flag = True
        elif state[64] == 0x31: # Close状態の場合
            posted_flag = False


# ここからスタート
if __name__ == '__main__':
    loop()

```

ソースコードを置いたら、`python3 post_check.py`を実行し、ポストに投函したらイベントがきちんと発生するか確認します。
ここでポストのセンサーと磁石の位置などを調整しましょう。

動作が正常に確認できたら、自動起動する設定を行います。

まず、実行するシェルスクリプトを作成します。以下のファイルを作成し、`/home/pi`以下に置きます。
置いたら実行属性を付けます。

```shell:postcheck.sh
#!/bin/bash
while true
do
        cd /home/pi
        python3 post_check.py
done
```

次に、Systemdで起動できるようサービスの定義ファイルを作成します。
以下の内容で/etc/systemd/system/postcheck.serviceに置きます。

```/etc/systemd/system/postcheck.service
[Unit]
Description = post check service

[Service]
ExecStart = /home/pi/postcheck.sh
Restart = always
Type = simple

[Install]
WantedBy = multi-user.target
```

置いたら、`systemctl list-unit-files --type=service | grep post`を実行し、postcheck.serviceが表示されることを確認します。
確認できたら、`sudo systemctl enable postcheck.service; sudo systemctl start postcheck.service`を実行し、自動起動するようにします。

# 動いたと思ったら
モノスティックブルーとAK-020を同時にさすと、通信がうまくできない現象が発生しました。
どうも先にモノスティック（FTDIのコントローラを使っている）が認識された場合、usbserialのドライバの関係でうまく動かなそうです。
困った。
と思ったら[こちら](https://soracom.zendesk.com/hc/ja/articles/360042108971-AK-020-%E3%81%A8%E4%BB%96%E3%81%AE-USB-%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E3%82%92-Raspberry-Pi-%E3%81%AB%E5%8F%96%E3%82%8A%E4%BB%98%E3%81%91%E3%82%8B%E3%81%A8-AK-020-%E3%81%8C%E8%AA%8D%E8%AD%98%E3%81%95%E3%82%8C%E3%81%AA%E3%81%84)に解決策が。

これで試してみると、先に自動起動させたサービスがシリアルポートを使ってしまっているため、正常に動作しません。
仕方ないので、Systemdを使った自動起動をdisableし、rc.localからチェックプログラムを実行させることにします。
こうすることで正常に通信とチェックプログラムの動作が確認できました。

```shell:rc.local
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

sleep 10s
sudo modprobe -r ftdi_sio
sudo modprobe -r usbserial
sudo modprobe usbserial vendor=0x15eb product=0x7d0e
sudo modprobe ftdi_sio
sudo ifdown wwan0
sudo ifup wwan0

bash /home/pi/postcheck.sh &

exit 0
```

# 実際に作ってみて
投函されたことがわかるので、無駄足を踏まなくなり非常に楽になりました。


# 今後の課題
- 起動時に通信が失敗したときのリカバリを入れないと。
- 家の中がかびないように環境モニターを入れたい。
- 庭の草取りのタイミングを監視したい。