RPi3で植物水やり自動化

# 背景

先日思い立って、ベランダにプランターを置き、ナスやピーマンを育てはじめました。
問題になるのが水やりです。
毎朝あげないといけません。

実は以前同様にベランダで枝豆を育てようとしたことがあったのですが、水やりを忘れて枯らしてしまった過去があります。
同じ轍は踏みたくありません。
そもそも、決まった時間に決まった動作を確実に行うというのを人間がやることにそもそも無理があります。
そういうのは機械にやらせるべきです。

というわけで自動的に作物に水をやるシステムを作ることにしました。

# ハードウェア

## 概要

拙いですが以下の図を御覧ください。

![plant.png](https://qiita-image-store.s3.amazonaws.com/0/189186/906989b4-0031-4662-c50b-71360e1219ac.png)

ベランダに設置したタンクの水をポンプで汲み上げ、ホースを介して植木鉢に散水します。
ポンプはリレーモジュールにつなぎ、Raspberry PiからON/OFFできるようにします。

防水が大変なので、リレーモジュールなどは屋内に設置することにし、ポンプだけベランダに出しました。
コードはエアコンのダクト用の穴を介して屋内に引き込みました。

タンクへの給水は手動です。１週間分は貯めておけるので、土日にまとめて入れています。

また水やりとはあまり関係ないですが、USBカメラで定期的に写真を取り、植物の成長の記録を残します。

## 材料

初めてなので、まずはあまり金をかけないという点を重視して揃えました。
ラズパイとUSBカメラはもともと持っていたので新規に買ってません。

* ポンプ
360円
https://www.amazon.co.jp/gp/product/B008OPKSC8/

* ホース
φ8mm, 100円/mくらい?
近所のホームセンターで購入

* ACアダプタ
899円
https://www.amazon.co.jp/gp/product/B077P769L7

* リレーモジュール
375円
https://www.amazon.co.jp/gp/product/B00L11KL10

* Raspberry Pi3 Model B
https://www.switch-science.com/catalog/3050/

* USBカメラ
https://www.amazon.co.jp/gp/product/B002EBBBCE

* タンク
発泡スチロールの容器とスーパーの袋でこしらえました。透明の方がホース、黒い方がポンプの電源ケーブルです。見た目は悪いですが金をかけずに用意できました。
<img src="https://qiita-image-store.s3.amazonaws.com/0/189186/cd3d4b6b-951f-b06c-f15e-3b3498806d44.jpeg" width=50%>


## 構成

USBカメラで撮影した写真が以下になります。
窓ごしにベランダを撮影しています。

![plant2.png](https://qiita-image-store.s3.amazonaws.com/0/189186/214fd77d-33af-e1fd-3ec8-0f38caa1ad05.png)

植木鉢の上で散水できるよう、先の尖ったピンセットをガスバーナーで加熱して突き刺し、ホースに穴を開けています。

## 注意点

[サイフォンの原理](https://ja.wikipedia.org/wiki/%E3%82%B5%E3%82%A4%E3%83%95%E3%82%A9%E3%83%B3)というものがあります。
タンク内の水面より、ホースの散水部分の位置が低いと、ポンプをOFFにしても水が流れ続けてしまいます。
タンクを低いところに置くことができなかったので、ホースに１箇所だけ空気を通す穴を開けてサイフォンが起こらないようにしています。

# ソフトウェア

## 概要

### ポンプON→OFF

Lチカ並にシンプルです。
第１引数に指定された数値の時間（秒）ポンプを作動させます。
購入したリレーモジュールは入力をGNDに短絡するとリレーがONになるので11番ピンをfalse(GND)にしています。

water.py

```python
import RPi.GPIO as GPIO
import time
import sys

if (len(sys.argv) < 2):
    print("notime")
    quit()

try:
    pump_time = int(sys.argv[1])
except Exception:
    print("bad time")
    quit()

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(11, GPIO.OUT)
GPIO.output(11,False)
time.sleep(pump_time)
GPIO.output(11,GPIO.OUT)
GPIO.cleanup()
```

### cron呼び出しスクリプト

cronで直接呼び出される処理を記述しています。

* 天気予報を確認し、雨が降りそうなときは散水量を少なくします。
[こちら](https://qiita.com/arabian9ts/items/6d4c0f3ede699598ce75)の記事のコードを拝借しました。
* 記録のため散水の様子を動画で撮影します。
参考：http://docoma.club/?p=763
* cameraディレクトリは別のファイルサーバをマウントしています。（SDカードに保存しているわけではありません）


takewater.sh

```bash
#!/bin/bash

RAINS=$(curl -s https://weather.yahoo.co.jp/weather/jp/14/4610/14110/******.html | tr '\n' ' ' | sed -e 's/<[^>]*>//g' | grep -oE ' - [0-9].*明日' | tr ' ' '\n' | grep -v '^$' | head -47 | tail -n 8 | awk '{SUM += $1}END{print SUM}')

echo "RAIN="$RAINS

PUMP_TIME=20
if [ $RAINS -gt 10 ]; then
    PUMP_TIME=10
fi

echo "PUMP_TIME="$PUMP_TIME

CAMERA_TIME=$((PUMP_TIME + 10))

ffmpeg -f v4l2 -s 1280x1024 -i /dev/video0 -t 00:00:$CAMERA_TIME -loglevel quiet /home/kaz/camera/$(date +%Y%m%d-%H%M%S).mp4 &
sleep 5
python /home/kaz/water.py $PUMP_TIME
sleep $((PUMP_TIME+5))

```

### 定期的な写真撮影

cronにより、１０分毎に画像を保存します。

```bash
#!/bin/bash

/usr/bin/fswebcam  /home/kaz/camera/$(date +%Y%m%d-%H%M%S).jpg -r 1280x1024 -S 10
```


# 振り返り

* 朝の忙しい時間帯にベランダに出て水をやるのはなかなか大変だったのですが、かなり楽になりました。  
  作物が増えても対応できそうです。
* 1本のホースですべての鉢に水をやるという方式にはやや難がありました。
ホースに穴を開けたりテープで塞いだりを繰り返し、ちょうどよい水量が与えられるように調整しました。
* 土壌の水分をセンサーで測定し、少なければ水をやる・・・ということもできそうです。