SORACOMとラズパイで郵便受けの中身を確認できるようにする

バッテリーが思った以上に保たなかったので改良版をつくりました。
[SORACOMとラズパイで郵便受けの中身を確認できるようにする(V2)](https://qiita.com/daikunjp/items/2f91313e85e02e8f6576)

## はじめに
みなさんコロナ禍をいかにお過ごしですか?
ボクはほぼ在宅勤務でとんとマンションから出ることがなくなりました。
で困るのが…郵便物の回収です。
用もないのに玄関の郵便受けまで行くのは億劫ですが…
**「もしかしたら！素敵な彼女からのラブレターが入ってるかも！」**
と思ってついつい用もないのに郵便受けを見に行ってしまい、空の郵便受けを見て肩を落とす…
こんな日が続いてました。

「じゃあ郵便受けに何が入ってるかわかればいいじゃん」
ってことで郵便受けの中をカメラで撮影してSORACOMのサービスで家や外出先から確認できる仕組みをつくってみました。

## 用意するもの

|品名|スイッチサイエンスでの価格|備考|スイッチサイエンスURL|
|---|---|---|---|
|Raspberry Pi Zero|1,848円|今回はZeroを使いましたがもちろん普通のRaspberry PiでもOKです|https://ssci.to/3646|
|Raspberry Pi Zero用スパイカメラ|3,135円|普通のラズパイカメラでもOKです|https://ssci.to/3323|
|USBドングル AK-020(※)|5,500円|SORACOM SIMで通信をおこなうためのモジュールです|https://ssci.to/5253|
|OnOffSHIM|1,100円|ボタンスイッチでRaspberry Piの電源操作ができます|https://ssci.to/3295|
|M5 ATOM Lite|1,300円|ESP32搭載で ~~RTCもついてる~~ DeepSleepが使えるので間欠動作のコントロールをさせます|https://ssci.to/6262|
|M5Stack用ミニリレーユニット|400円|ATOM Liteにつないでボタンスイッチの操作をさせます|https://ssci.to/4054|
|USB LEDライト|100円|郵便受けの中を明るくして撮影しやすくします|100円ショップで売ってます|

(※)SORACOM SIMをお持ちでない場合はSORACOMスターターキット（3G USBドングル AK-020同梱）のほうが通信量1000円分のクーポンもついてお得です
https://www.switch-science.com/catalog/2767/

## 全体構成図

全体はこのようになっています。
主な技術的ポイントは以下のとおりです。
* ラズパイの写真撮影/クラウド送信はプログラム開発無し(コマンド実行のみ)
* ラズパイでバッテリーを保たせるために安価な間欠動作制御(3000円程度で間欠制御※)
* SORACOMサービスを使うことで画像保管/見える化を安価に実装(月額200円くらい)

![ポストカメラ全体構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142746/c702fe2a-f403-0330-f9ba-3e61ceba1e42.png)

※は別記事に詳細を書きました。こちらもご覧ください。
[M5 ATOM LiteでRaspberry Piを間欠動作させる](https://qiita.com/daikunjp/items/c6bbfd62927311e5dbcd)

## 各種設定
### Raspberry Pi Zero セットアップ

Raspberry Pi Imagerを使ってSDカードにOSをセットアップします。
できるだけ軽いほうがいいので`Raspberry Pi OS Lite(32-bit)`を選択してSDカードを作成。
ラズパイに挿して起動したあとに所々の設定をおこないます。
ボクの場合はこんな手順です。
[Raspberry Pi 初期セットアップメモ](https://qiita.com/daikunjp/items/d9f6d34300bba63fc05f)

### SORACOM通信設定

USBドングルはABIT AK-020を使用ました。
以下のサイトを参考にしました。
[Raspberry Pi と USB モデム](https://users.soracom.io/ja-jp/guides/devices/general/raspberry-pi-dongle/)

```
% curl -O https://soracom-files.s3.amazonaws.com/setup_air.sh
% sudo setup_air.sh
```

再起動して接続されているかを確認します。

```
% ifconfig -a
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 1  bytes 29 (29.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1  bytes 29 (29.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ppp0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1464
        inet 10.199.180.xx  netmask 255.255.255.255  destination 10.64.64.64
        ppp  txqueuelen 3  (Point-to-Point Protocol)
        RX packets 28  bytes 298 (298.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 29  bytes 697 (697.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.xxx.xxx  netmask 255.255.255.0  broadcast 192.168.xxx.255
        ether b8:27:eb:86:d0:8a  txqueuelen 1000  (Ethernet)
        RX packets 145  bytes 13749 (13.4 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 121  bytes 19350 (18.8 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wwan0: flags=4291<UP,BROADCAST,RUNNING,NOARP,MULTICAST>  mtu 1500
        inet 169.254.106.110  netmask 255.255.0.0  broadcast 169.254.255.255
        ether 7e:a0:25:03:19:18  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1  bytes 359 (359.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
```

無線LANと両方つながってますが、いろいろいじるのに無線LAN経由でやるほうが楽なのでこのままで。
経路情報を確認するとデフォルトはSORACOM側を向いているので良しとします(家のLANは一つのセグメントなので…)

```
% netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         0.0.0.0         0.0.0.0         U         0 0          0 ppp0
10.64.64.64     0.0.0.0         255.255.255.255 UH        0 0          0 ppp0
169.254.0.0     0.0.0.0         255.255.0.0     U         0 0          0 wwan0
192.168.xx.0    0.0.0.0         255.255.255.0   U         0 0          0 wlan0
```

### SORACOM Harvest Files の準備

撮影した画像ファイルを SORACOM Harvest Files に送るため設定をします。
まずは設定するためのSIMグループを作成。
![RaspberryPiZero-camera1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142746/a0c216e0-a12c-fa0c-9073-4278b9fa54b5.png)

つぎにHarvest Files を有効化します。
![RaspberryPiZero-camera2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142746/92abb557-a43a-1137-19ff-d92d6f8a8a29.png)

SORACOM Harvest と HARVEST DATA 連携をオンにして連携対象のパスは`/PostCamera/*`としておきます。
これでHarvest Files の `/PostCamera/*` にポストされたデータのURLがHARVEST DATAに連携されます。
あとで見える化の画面を作成するときに利用します。

次に作成したSIMグループに使うSIMを登録します。

![RaspberryPiZero-camera3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142746/37adb8a9-5a02-a41f-6232-0a90436511a3.png)

![RaspberryPiZero-camera4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142746/b8d34c83-9948-3929-1ea3-7a57d0ae1dea.png)

これで画像を送信する準備ができました。

### 画像の撮影と送信の確認

以下のコマンドで画像を撮影して送信してみます。

```
# raspistill -w 640 -h 480 -e png -o image.png
# curl -v -X PUT --data-binary @image.png -H "content-type:image/png" http://harvest-files.soracom.io/PostCamera/image.png
```

### Harvest Files でファイルの確認

SORACOMコンソールからHarvest Filesにデータが入ってることを確認します。
ファイル名`image.png`が送信した日時で作成していればOKです。

### 画像確認画面の作成

Harvets Files ではダウンロードしないと中身が確認できないしダウンロードすると月20円(1GBytesまで)かかっちゃうので最新の画像を確認できる画面をSORACOM Lagoon で作成します。
SORACOM Lagoon は1ユーザーでダッシュボード1つなら無料で使えるありがたいサービスです。

Harvest Files に保存された画像ファイルを表示させる手順はこちらのサイトの「ステップ 3: SORACOM Lagoon で Harvest Files に保存したデータを表示する」を参考におこないます。
https://users.soracom.io/ja-jp/docs/harvest/lagoon/

上記に加えてタイトル変更やタイムスタンプの追加などをおこないました。
以下が設定した内容です。
![RaspberryPiZero-camera-Lagoon1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142746/12838b06-a3d0-f8ef-1107-422cf2b3150d.png)

ついでにいつアップロードされた画像ファイルかわかるように Harvest Data のテーブルも追加します。
左上の `Add panel` を選択して `+ Add new panel` ボタンを押します。
![RaspberryPiZero-camera-Lagoon2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142746/919b8388-b9d2-5e61-9c57-8d1d9dd2f8e2.png)

Visualization で Table を選択し Query で使用しているSIMの名前を選び Table を選択します。
![RaspberryPiZero-camera-Lagoon3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142746/68f2b4d5-c42e-24fe-c062-83785bdcf12f.png)

そのままだとすべて表示されてしまうので Transform タブで `Sort by` と `Qrganize Fields` を使ってtimeとurlのみ表示されるようにします。
![RaspberryPiZero-camera-Lagoon4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142746/e74e5cb1-6dfa-eadc-d62c-72e07ae4d4d8.png)

最終的な画面はこんな感じ
![RaspberryPiZero-camera-Lagoon5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142746/a798fbfe-85ee-f1c7-4de3-1f2e7df11fe3.png)

## デバイスの準備

それでは郵便箱の中に置くカメラや画像ファイルを送信する仕組みを作成していきましょう。
先程のコマンドで画像ファイルをSORACOMに送信することができるので`cron`などで定期的に画像を送る仕組みを作ってもいいのですが、バッテリーで動かすため稼働時間が気になります。
そこでRaspberry Piを間欠動作させてバッテリーを長持ちさせてみます。

Raspberry Pi を間欠動作をさせるためのデバイスはいくつかあるのですが(例えば https://mechatrax.com/products/slee-pi/ など)どれも1万円以上するので個人で遊びに使うのは少し勇気と財力が必要です。
そこでM5 ATOM LiteとOnOffSHIMを使ってRaspberry Piを間欠動作させてみました。
部品の準備や動作説明については別記事にまとめましたので、そちらをご覧ください。
[M5 ATOM LiteでRaspberry Piを間欠動作させる](https://qiita.com/daikunjp/items/c6bbfd62927311e5dbcd)

### Raspberry Piの画像送信設定

定期的に間欠動作させるので Raspberry Pi は起動したらすぐに写真を撮影してSORACOM Harvest Files に画像を送信しシャットダウンするようにしておきます。

以下のようなスクリプトを作成します。

```/usr/local/bin/cam-upload.sh
#!/bin/sh
RASPISTILL="/bin/raspistill"
CURL="/bin/curl"
WORKDIR="/tmp"
SHUTDOWN="/sbin/shutdown"
IFCONFIG="/bin/ifconfig"
LOGFILE="/var/log/cam-upload.log"
# LOGFILE="/dev/null"

sleep 60

echo "[start :  `date`]" >> $LOGFILE
$IFCONFIG ppp0 >> $LOGFILE 2>&1
$RASPISTILL -t 5 -n -w 320 -h 240 -e png -o $WORKDIR/image.png >> $LOGFILE 2>&1
$CURL -v -X PUT --data-binary @$WORKDIR/image.png -H "content-type:image/png" http://harvest-files.soracom.io/PostCamera/image`date "+%Y%m%d_%H%M%S"`.png >> $LOGFILE 2>&1
echo "[end :  `date`]" >> $LOGFILE

$SHUTDOWN -h now
```
基本的には先程テスト送信したときと同じコマンドです。
`sleep 60`で1分ほど待っているのはUSBドングルでSORACOMに接続されるのに少し時間がかかるようなので1分ほどWAITしています。(ほんとはインターフェイスの状態を見るべきなんですが…めんどくさかったので)
デバッグのためインターフェイスの状態やコマンドの実行結果をログファイルに出力しています。安定稼働するようであればコメントにあるように`/dev/null`に出力して捨てればよいです。

起動時に上記のスクリプトが起動するように`/etc/rc.local`に記述します。

```/etc/rc.local
(前略)
# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

# CAM Upload Script(この2行を追加)
/usr/local/bin/cam-upload.sh &

exit 0
```

### 間欠動作ハードウェアの準備

間欠動作には M5 ATOM Lite を使用します。
1000円ちょっとで買えて ~~RTCも内蔵してる~~ DeepSleepが使えるので間欠動作をコントロールさせるのにはバッチリです。

まず OnOffSHIM をRaspberry Pi の GPI に挿して、以下のコマンドで OnOffSHIM から Raspberry Pi の電源オン/シャットダウンを行えるようにします。

```
% curl https://get.pimoroni.com/onoffshim | bash
```

つぎに ATOM Lite - ミニリレーユニットに接続します。
![OnOffSHIM6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142746/4140c5e7-1093-7acb-4693-5e3d297de3ff.jpeg)
今回はリレーに電流を流したときだけクローズしたいのでNO(ノーマルオープン)の真ん中の端子を使います。

M5 ATOM Lite に間欠動作のプログラムを書き込みます。
Platform.IO でビルドできるプログラムはこちらで公開しています。
https://github.com/daikunjp/m5atom-relay

単純なプログラムなのでArduino IDE でも動くと思います。

```main.cpp
#include <M5Atom.h>

#define SWITCH 26
#define SLEEPTIME 3600000000 /* 1000000マイクロ秒 × 3600 */

void setup() {
  M5.begin(true, false, true);
  pinMode(SWITCH, OUTPUT);
  // 一回LOWにしとかないとうまく起動してくれない
  digitalWrite(SWITCH, LOW);
  Serial.print("switch low ");
  delay(1000);
  // 3秒くらいONにしないと起動しないときがある
  digitalWrite(SWITCH, HIGH);
  Serial.print("switch high");
  delay(3000);
  digitalWrite(SWITCH, LOW);
  Serial.print("switch low");
  esp_deep_sleep(SLEEPTIME);
}

void loop() {
}
```

### デバイスの設置

郵便箱にデバイスを設置していきます。
カメラは上から撮影させたいので Raspberry Pi Zero を入れて固定するための箱を用意します。
100円ショップで購入したもの(たぶん小物入れか化粧入れか？ ^_^;) に半田コテやニッパー、ヤスリを駆使して必要なところに穴を開けます。
![PostCamera1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142746/ceaefd4f-d413-037b-8fec-2e21fbca4dc7.jpeg)
![PostCamera2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142746/3593dd7f-26df-e4e8-7289-200cb9550f40.jpeg)

これを郵便箱の上部にガムテープで貼り付けて他の部品やモバイルバッテリー(家にあった一番大きなやつ 21000mA)も郵便箱の中に配置します。モバイルバッテリーの1つの口にはUSB-LEDライトをつけて郵便受けの中を明るくしています。
![PostCamera3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142746/79b83949-2266-386c-9c99-31afb7c65c25.jpeg)

![PostCamera4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142746/ad41db95-6a87-d361-6d00-874d77c6e174.jpeg)

## まとめ

これでいつでもどこでも郵便受けの中が確認できるようになりました。

PCで見た画面
![Lagoon-PostCam-PC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142746/494b631d-074b-2788-48d7-40c9ab82152d.png)


スマホで見た画面
![Lagoon-PostCam-SmartPhone.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142746/5a07740a-dd68-05f4-1587-219faccd3ad6.png)

どちらも不味そうなところにはモザイクいれましたが氏名とかはそのままです。
かろうじて文字が読めるか読めないかといったところでしょうか。
なんとなくどんな郵便物が届いているかはわかります。

気になるお値段ですが…初期費は最初の「用意するもの」で書かせていただきましたが全部買い揃えるとトータル14,000円程度です。
通信や画像ファイル置き場、見える化にSORACOMサービスを使いました。
こちらがだいたい月額500円程度といったところでしょうか。

あとはバッテリーがどのくらい持つかについては、これからしばらく動かしてみてこちらでご報告させていただきます。

## 今後やってみたいこと
今後チャレンジしたいことも書いておきます。(やるとは言わない…^_^;)

### ラズパイのデーモンプロセスを減らす
今回ラズパイの起動プロセスはデフォルトのままですが crond とか必要ないものも多いです。
要らないデーモンプロセスを減らすことで起動・停止が早くなって電池の持ちが良くなると思います。

### LEDライトを間欠動作させる
別の記事にも書きましたがモバイルバッテリーを休止させない目的もあるのでLEDライトは点けっぱなしです。
夜、郵便受けを見るとそれほどではないですが薄っすらと光ってて近所の人に気味悪がられるかも。
別の方法でモバイルバテリーを休止させないようにすれば撮影時だけLEDを光らせることで電池の保ちをよくできるかもしれません。
(いきなり光るとそれはそれで気味悪がられるかもしれませんが…)

### 測距センサーなどで検知したときに起動して写真を取るようにする
たとえば物体検出センサ( https://ssci.to/7016 )などで郵便物が届いたときだけ撮影するようにすると郵便物が届いたことをメールやSlackなどで知らせて画像も確認できる…といったことができそうです。

### 古い画像ファイルの削除
SORACOM Harvest Files は約2年(731日)後に自動削除されますが、そんなに要らないし保存ファイルサイズが1GBを超えると1G毎に200円/月がかかってしまいます。
Raspberry Pi で画像を送信する前か後、あるいは [AWS Lambda](https://aws.amazon.com/jp/lambda/) あたりで古い画像を削除する処理を作成しようと思います。

「SORACOM Harvest Files に [Amazon S3](https://aws.amazon.com/jp/s3/) みたいなライフサイクルポリシーが設定できればいいのになぁ。設定した日時が経つと勝手に消してくれるやつ。」

と思ったのでソラコムサンタにお願いしておきました。

https://twitter.com/daikunjp/status/1399495780197486602

叶えてくれるといいなぁ。