郵便が届いたらメールで通知してくれるIoTポストを距離センサとラズパイで作ってみたよ

# はじめに
皆さんは日頃どのタイミングで家のポストの中身を確認しますか？
おそらく、ほとんどの方は帰宅時に確認すると思います。
わざわざポストの前に赴いて、ロックを解除して、蓋を開けて確認する。
ポストの中を確認するという作業は地味にめんどくさいです。

あらかじめポストの中に郵便物が入っているかどうかがわかれば、無駄な確認作業が無くなり小さなストレスから開放されます。
わざわざ見に行ったのに、中に何もなかったときはがっかりしますよね。
では、具体的にどうするのかというと、デバイスとセンサで郵便を検知します。
ポストにデバイスを取り付けて、郵便が入ったらセンサで検知、そしてメールでユーザに知らせます。
いわゆるIoT(Internet of Things)というやつですね。
今回はポストをIoT化することにしました。具体的なパーツとしてはRaspberry Pi、ToF式距離センサ、サービスとしてはSORACOM Air、SORACOM Harvest、SORACOM Lagoon、IFTTT、Gmailを使っています。

# IoTポストの要件を決める
それではシステムを開発してきましょう。まずは前提条件の確認です。
私の家のポストは下のイラストのような集合住宅にあるタイプで、上の口から郵便を入れる形になっています。
郵便を入れる口に蓋はついていません。このポストに後付けでデバイスをつけます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62268/42214602-1ea8-ee08-be43-0db24bbac47e.jpeg" width=50%>


## ゴール
- ポストに郵便物が入っている状態を検知できること
    - 郵便物が入る瞬間を検出する必要はありません
- 検知したらインターネットを介してメールで通知できること

## 郵便の検出方法
郵便物の検知方法は２通りあって、１つ目はポストの蓋の動きを検知する方法、２つ目はポストの中の底から天井までの距離を測る方法です。

1つ目は蓋の動きを検出する方法で、センサとしてはリードスイッチがよく使われています。
ポストの蓋と側面に磁石をリードスイッチを取り付ければ、郵便物が入れられたときに近接するので、投函の瞬間を検出できます。
ポストは金属製でできていることが多く、磁石をくっつけられるためほとんどのIoTポストはこの手法を用いています。
・[郵便がポストに届いたら LINE で通知がくるようにした - Qiita](https://qiita.com/task_jp/items/85ccc04a00982569f6c5)
・[郵便ポストをIoT化 Ver.2 - Qiita](https://qiita.com/hina03/items/99df273fbe932dd04941)
・[家のポストに荷物が投函されたらSlackに通知が来るIoTやってみた - Qiita](https://qiita.com/Yuta_Fujiwara/items/8adf89f8b5b89d75ae64)
・[あの日、自転車を撤去された私は、IoTポストの制作に取り掛かった。｜imaimai｜note](https://note.com/imaimai/n/n82f5da466c85)
・[SORACOM LTE-M Button Plusと100均ショップの商品でIoTポストを作ってみた | DevelopersIO](https://dev.classmethod.jp/articles/soracom-lte-m-button-plus-iot-post/)

この方法のメリットとしては郵便が来た回数を正確にカウントできることです。デメリットとしては、ポストから郵便物を取り除いても検知できないことです。
ただ、この手法を用いるには前提としてポストが蓋付きの必要があります。
しかし、私の家のポストにはありません。そのため別の方法を用いることにしました。

２つ目はポストの中の底から天井までの距離を測る方法です。
郵便物が中に入ったときにポストの内部で変化することといえば、底からの距離です。
下の図のように郵便が空であったらポストの底からの距離は天井までになりますが、郵便があると距離は底から郵便物までになります。
この違いをセンサで検出できれば郵便物の有無を検知できます。
実装も難しくないことから、今回はこの方法を採用することにしました。

![ポストの中.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62268/59c72cc5-6a28-ba40-fc59-3b70714d24fb.png)

距離センサにも色々ありますが、光を出力して反射して返ってくるまでの時間から距離を測定するToF（Time of Flight）式のセンサを使うことにします。このセンサのメリットは小型で、精度が高いことです。他だと超音波距離センサがメジャーです。費用が安いですが、ToF式センサに比べるとサイズが大きく、対象物までの距離が近すぎると検出できないという話もあって不採用としました。

## デバイス要件
センサデータを取り扱うデバイスを選びます。
開発のしやすさからLinuxベースのRaspberry Piにしました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62268/ca07ce61-9938-f6fe-1f6a-98078d553bf9.png" width=70%>

Bluetooth、Wi-Fi、USB接続、I2C対応など、便利すぎてIoT開発の鉄板ですね。
デバイスをポストに入れることになりますが普通のRaspberry Piは大きすぎます。
そこで、今回は小型なRaspberry Pi Zeroを使うことにしました。
また、ポスト内には電源はありません。
モバイルバッテリーを一緒に入れることになりますので、電力消費量が少ないと嬉しいです。
そういう意味でもRaspberry Pi Zeroが適任ということになりました。

## インターネット
IoT開発でいつも問題になるのがインターネットです。
部屋にWi-Fiが飛んでいたとしても、部屋からポストまでの距離は遠いのでもちろん届きません。
そこで、IoT向けのセルラーネットワークを提供しているSORACOMのSORACOM Airを活用します。
SORACOM Airは携帯の通信網に直接接続するので、どんな場所からでもインターネットに接続可能です。
通信量で課金されますが、数十分おきにセンサデータを送るだけなので、かかる費用は少ないと見積もっています。

## 郵便の通知
インターネットに接続できたら後はその旨を通知するだけです。
メール、SMS、Twitter、LINE、Slack、スマホの通知といろんな方法がありますが、そこは個人の好みになります。
私はよく確認するメールへ通知することにしました。

それと、センサデータから郵便の有無を判別する処理が必要です。デバイス上で判断しても良いのですが、SORACOMのHarvest（データの集約サービス）とLagoon（データの可視化サービス）を利用していたのでこちらの機能を活用します。Lagoonにはデータの値を判断してアラートを送れる機能があります。今回の場合ですと、距離センサの値が小さくなったら郵便が来たと判別します。その後にメールで通知するという流れになります。
ただ、デフォルトのメール機能は監視システム用のフォーマルな内容ですので、別の方法でもメールを送ってみます。様々なサービスの連携が得意なIFTTTというサービスがあり、Gmailを連携できます。LagoonはWebhookにも対応していますので、郵便を検知したらGmailを送信する仕組みを作れます。

# IoTポストシステム
## システム全体の構成
まとめた要件をもとにシステムの構成図を作りました。楽に作りたかったのもありSORACOMのPaaSを最大限に活用しています。

![system.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62268/1476a51d-3aac-1db2-04d3-f71aa0d5b6df.png)

## デバイスの構成
デバイスの構成は以下になります。ツギハギ状態なので見た目は悪く、お恥ずかしいところです。
![devices.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62268/5b0e1c51-3ba5-43a4-6f46-0163c14a66f5.png)

### パーツリスト

| 名称 | 用途 | 値段 |
|:-----------|:------------|:------------|
| Raspberry Pi Zero スターターキット | デバイス | 4,400円 |
| VL53L0X Time-of-Flight 距離センサモジュール | 距離センサ | 1,550円 |
| SORACOMスターターキット（3G USBドングル AK-020同梱） | USB型データ通信端末 | 6090円 |
| Ankerのモバイルバッテリー | バッテリー | 約4,000円 |
| その他もろもろ | スペーサー,ピンヘッダ,ブレッドボード... |  |
| 合計 |  | 16,040円 + α |

# 実装

## Raspberry Piの設定
使用したOSは`Linux rapberrypi 5.10.17+`です。
GUIは使わないのでNo Desktop版をインストールしました。
今は`Raspberry Pi Imager`なんて便利な公式ソフトがあるんですね。
- [Raspberry Pi 初期設定 - Qiita](https://qiita.com/HeRo/items/c1c30d7267faeb304538)
を参考にsshやインターネットの設定などの初期設定をします。
python、smbus、git、pipなどをインストールしましょう。
`raspi-config`でI2Cを有効にしておきましょう。

## 距離センサデータの取得
各パーツを気合ではんだ付けしたら、Raspberry Piと距離センサをジャンパーワイヤで接続します。
通信方式はI2Cですので、VDD、GND、SDA、SCLが必要な端子となります。
ちなみに、今回はRPZ-IR-Sensorという環境センサ（照度、温度、湿度）も実装しているのですが、郵便検知には関係ないので説明は省かせてもらいます。
有志の方がVL53L0Xの接続ライブラリを公開しているのでこれを活用します。
・[johnbryanmoore/VL53L0X_rasp_python: Python interface to the VL53L0X ST Library](https://github.com/johnbryanmoore/VL53L0X_rasp_python)
`python/VL53L0X_example.py`が動作できたらおｋです。がんばりましょう。

## SORACOMの設定
公式資料を参考にSORACOM AirでRaspberry Piを携帯回線網に接続します。通信用ドングルがRaspberry Pi Zeroに対応してるかどうか確認せずに購入していて、少しヒヤヒヤしていましたが問題なく動作できました。よかったです。
ちょっと注意することといえば、Raspberry Pi Zeroは片方のUSBが電源用（POWER IN）、もう片方のUSBがデータ通信用（USB）となります。AK-020はデータ通信用のポートに接続しましょう。

・[Raspberry Pi Zero (W) + USB セルラーモデムで SORACOM に接続する - Qiita](https://qiita.com/ma2shita/items/c9d0e5a981c02cf58c5e)
・[Getting Started: Raspberry Pi と USB モデム | 各種デバイスで SORACOM Air を使用する | SORACOM Users](https://users.soracom.io/ja-jp/guides/devices/general/raspberry-pi-dongle/)

## SORACOM Harvestへのデータ送信
SORACOM Harvestというデータの蓄積サービス（DBaas）にセンサデータを集約します。
SIMの契約と同時に準備しましょう。SIMのグループを作らないとサービスを選択できないので注意です。

![harvest.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62268/ea64bde7-da8f-ceb0-b414-b74b5fd8d4d1.png)

データはJSON形式に加工してHTTP通信で送ります。データ構造は自由のようで、スキーマを設計する必要がなく便利に感じました。
Pythonだと次のような関数で送信できます。`data`は`{value: 100}`みたいな辞書型のデータです。

```python
import requests

def post_data(data) -> bool:
    response = requests.post(
        "http://harvest.soracom.io",
        json.dumps(data),
        headers={"Content-Type": "application/json"},
    )
    return response.ok
```


## スクリプトの実行
`iotpost.py`のような実行したらセンサデータを取得してHarvestに送信するスクリプトを組みました。cronを使ってこのスクリプトを定期的に実行します。Raspbrry Piにはデフォルトでcronが入っているようなのでインストールは不要です。
`$ crontab -e`で設定ファイルを以下のように設定します。この例では10分ごとにスクリプトを実行するという意味になります。
`*/10 * * * * python3 /home/pi/iotpost.py`

## 郵便の検知とメールでの通知

### IFTTTの設定
[IFTTT](https://ifttt.com/home)はif-thenに基づいてWebサービス同士を連携できるサービスです。
今回は、[Webhooks](https://ifttt.com/maker_webhooks)とGmailを連携させます。
`https://maker.ifttt.com/trigger/hogehoge/with/key/hugahugahuga`
のようなURLにGETかPOSTでアクセスするとGmailが送られるように設定します。

### SORACOM Lagoonへの連携
SORACOM LagoonはHarvestのデータを可視化・監視するシステムです。1ダッシュボードだけ無料で使えます。値がしきい値を超えたり、下回ったときに通知をする仕組みが作れます。今回の場合だと、距離センサの値がある値を下回ったら郵便が来たと判別し、メールを送信します。

![可視化.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62268/b29e8861-46bf-fac6-cf9c-e5a488d70c44.png)

### 通知設定

はじめにNotification channelsを設定します。`type: mail`だとSORACOM Lagoonからメールが送られてきます。`type: webhook`には先程連携したIFTTTのWebhookのURLを指定します。

次にAlert Rulesで通知の判別設定をします。Conditionsでしきい値を設定して、先程作成したNotificationsをSend toに設定します。データを10分ごとに送信するとしたとき、Lagoonの評価の間隔が10分よりも短いとデータがない（No Data）と判別されることがあり、異常事態ということでメールが送られてしまいます。
間隔の設定を確認するのと、If no data or all values are nullを`Keep Last State`と設定しましょう。

詳細な設定方法は公式ドキュメントを参照ください。
- [Getting Started: Alert を設定する | SORACOM Lagoon | SORACOM Users](https://users.soracom.io/ja-jp/docs/lagoon-v2/setup-alert/)

# 設置してみる
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62268/f86c0073-c31f-8a16-4d81-7ae9859fcfa1.jpeg" width=750%>

実際に設置してみるとこんな感じになります。
基盤むき出しの状態なので見栄えは良くないですね。
バッテリー、通信用ドングル（AK-020）、Raspberry Piがチカチカ光ってしまうのが気になるところで、角度によってはLEDの光が見えてしまうことも。
他の住人に変なことをしていると怪しまれないように配慮したいです。

## 郵便投函テスト

設置ができたところで実際に投函して動作をテストします。投函したのは市報とかチラシです。

下のグラフは横軸が時間、縦軸が距離センサの値を示しています。単位は[mm]で、何も入っていない状態、つまり、ポストの底から天井までの距離が約23cmです。
郵便物を投函すると20:10から20:20のタイミングで距離センサの値が小さくなりました。この値はポストの底から郵便物までの距離を表していて、実測値だと3cmになります。検知のしきい値は5cmと設定しているので、それより小さい値になったことからLagoonの監視機能が働いて検知状態に入ります。そして、その状態が20分程度続くと郵便物が入っていると確定して、メールが送信されます。

![郵便検出 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62268/cc559078-f4f5-9379-ea61-d79ccc337d08.png)

実際に届いたメールが下になります。IFTTTを経由したGmailが1通目で、SORACOM Lagoonからのメールが2通目です。大きな問題もなくシステムが実行できました。

![mail.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62268/f7234daa-9ff7-8a36-21d2-f0bf6857ac03.png)

# まとめ
ということで、 Raspberry Pi Zero、ToF式距離センサ、SORACOMを使ってIoTポストを構築しました。このシステムによってポストに投函された郵便を検知・メールで通知してくれるので、ポストの中身を確認するという面倒な作業が必要なくなりました。
プロトタイプにしては少ない工数でシンプルに作れたのかなと思っています。

システムの改良点を挙げるとしたら、今は基盤が丸出しでセンサをブレッドボードに挿している状態なのでガワを良くしたいです。
それと、今回は使っていないですが環境センサ（温度・湿度・照度）も実装しているので何かに使えないかなと考え中。
これから夏になっていくわけですが、リチウムイオンバッテリーと熱は相性が悪いです。外気に強いバッテリーを探したいところです。

今後実運用していって、その内容に関しては後日記事にまとめようと考えています。
運用方法、電力消費量、通信量、維持コスト、検出精度などが報告できたらなと思います。