Raspberry pi と scansnap で スタンドアローンなクラウドスキャナを作る

# 目的

家には Fujitsu の scansnap 1300i があるのですが、これ自体にはOSが入っていないので、普通はWindowsマシンかMacに接続することが必要です。

これと Raspberry piを使って、クラウドスキャナにすることを目指します。
最終的には、
1. スキャナのボタンを押すと、書類がスキャンされて
2. それを自動でPDFに変換し、
3. Evernote や google keep にアップロードする
ところまでやらせたいです。

とりあえず今回は、スキャン結果をメール添付で送るところまでを行います。

# 参考

以下のページ
http://howto.philippkeller.com/2018/02/08/Scan-with-raspberry-pi-convert-with-aws-to-searchable-PDF/
が非常に参考になりました。
ただAmazon web serviceを多用していて、ちょっと敷居が高いので、ローカルである程度処理出来るようにします。

# 概要
1. Raspberry pi に SANE をインストールして、スキャナを認識させる
2. scanbd をインストールして、スキャナのボタンを認識させる
3. スキャンボタンが押されたときに起動させるスクリプトを作成する
という手順で進めます。

# SANEのインストールとスキャナのセットアップ
まずは `sane-utils` をインストールします。`sane`に含まれる全機能は必要ないので、より軽量の`sane-utils`にします。

```
sudo apt install sane-utils
```
インストールしたのち、スキャナを接続して

```
sudo sane-find-scanner -q
```
を実行すると、以下のようなメッセージが返ってくるはずです。

> found USB scanner (vendor=0x04c5 [FUJITSU], product=0x128d [ScanSnap S1300i]) at libusb:001:004


ユーザ pi に接続権限を付けるため scanner グループに追加します。

```
sudo usermod -a -G scanner pi
```

次に、スキャナに必要なドライバをインストールします

```
grep 1300i /etc/sane.d/*.conf
```
とすると、

> /etc/sane.d/epjitsu.conf:# Fujitsu S1300i
> /etc/sane.d/epjitsu.conf:firmware /usr/share/sane/epjitsu/1300i_0D12.nal

的なのが表示されると思います。

今回は、S1300iというスキャナを繋いでいますが、その場合 `1300i_0D12.nal` というファイルが必要です。
インターネットに転がっているので、適当にダウンロードします。
私はここから見つけました。
https://github.com/stevleibelt/scansnap-firmware

```
sudo mkdir -p /usr/share/sane/epjitsu/
sudo wget https://github.com/stevleibelt/scansnap-firmware/raw/master/1300i_0D12.nal -O /usr/share/sane/epjitsu/1300i_0D12.nal
```

少し、権限関係がややこしいので、まずは以下が管理者権限で実行できるか調べます

```
sudo scanimage -L
```
として、スキャナが見つかると
> device `epjitsu:libusb:001:004' is a FUJITSU ScanSnap S1300i scanner


スキャナが見つかるようなら以下のコマンドを実行して、実際にファイルがスキャンできるかどうか確かめます

```
scanimage /tmp/out.pnm
```
スキャナが見つからない旨を言われると、少し操作が必要です。

具体的には
https://wiki.archlinux.org/index.php/SANE#Permission_problem
に書いてありますが、

`/etc/udev/rules.d/49-sane-missing-scanner.rules` にルールを追加する必要があります。


まず`lsusb`をして、ベンダーIDや製品IDを見つけます

```
lsusb
```

> Bus 001 Device 004: ID 04c5:128d Fujitsu, Ltd 
> Bus 001 Device 003: ID 0411:016f BUFFALO INC. (formerly MelCo., Inc.) WLI-UC-G301N Wireless LAN Adapter [Ralink RT3072]
> Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub
> Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

ここで、`04c5`がベンダーIDで、`128d`が製品IDです。

```
sudo nano /etc/udev/rules.d/49-sane-missing-scanner.rules
```
に以下を記入します。

```
ATTRS{idVendor}=="04c5", ATTRS{idProduct}=="128d", MODE="0664", GROUP="scanner", ENV{libsane_matched}="yes"
```
`04c5`,`128d`の部分は適宜変更してください。


```
scanimage > /tmp/out.pnm
```
を実行して、スキャンされると成功です。


# scanbd のインストール

scanbd はスキャナのボタンを検出するソフトウェアです。
ただ挙動（仕様）が少し変で、これをインストールすると

```
scanimage
```
でスキャナを認識しなくなります。

この仕様に気づかずに何時間も無駄にしました。

```
sudo apt install scanbd -y
```
でインストールしたあと、

```
/etc/scanbd/scanbd.conf
```
を以下のように変更します。

```
debug-level = 3
user = pi
action scan {
        filter = "^scan.*"
        numerical-trigger {
                from-value = 1
                to-value   = 0
        }
        desc   = "Scan to file"
        script = "scan.sh"
}
```

これで、スキャナのボタンを押すと、`/etc/scanbd/scripts/scan.sh` が実行されるようになります。
とりあえずのスクリプトを作ります。

```
sudo mkdir /etc/scanbd/scripts/
echo -e '#!/bin/sh\nscanimage > /tmp/foo.pnm' | sudo tee /etc/scanbd/scripts/scan.sh
sudo chmod a+x /etc/scanbd/scripts/scan.sh
```

raspberry pi を再起動して、`scanbd`を実行してみます。

```
sudo scanbd -f
```
この状態でスキャナのボタンを押したのち、スキャンが始まればうまくいっています。

systemd にscanbdをdaemonとして登録します。

```
sudo systemctl daemon-reload
sudo service scanbd start
sudo update-rc.d scanbd enable
```

# OCR, pdf化スクリプトの作成
OCRをするために `tesseract-ocr` をインストールします。

```
sudo apt install tesseract-ocr
sudo apt install tesseract-ocr-jpn
```
これを使って

```
tesseract -l jpn -c min_orientation_margin=0 file_in.pnm file_out pdf
```
とするとファイルをOCRしたpdfファイルを作ってくれます。
とりあえず以下のスクリプトを登録します。
スキャンしたファイルをocrして、複数ページpdfとして `/tmp/output.pdf` に書き出してくれます。

# メールクライアントの設定

今回はスキャンしたファイルをまずメールで送ります。
そのため、`msmtp` をインストールします。

```
sudo apt install msmtp
sudo apt install mutt
```

念の為、タイムゾーンも設定しておきましょう

```
sudo dpkg-reconfigure tzdata
sudo dpkg-reconfigure locales
```

msmtp の設定をします。

```
sudo nano /etc/msmtprc
```

```
# Set default values for all following accounts.
defaults
auth           on
tls            on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile        ~/.msmtp.log
# Gmail
account        gmail
host           smtp.gmail.com
port           587
from           [account]@gmail.com
user           [account]@gmail.com
password       [password]

# Set a default account
account default : gmail
```

またmuttの設定ファイルに

```
sudo nano /etc/Muttrc
```
以下の一行を加えます

```
set sendmail = "/usr/local/bin/msmtp"
```

以下のコマンドでメールが送れればうまくいっています。

```
echo "Subject: Test again\ntest test" > mail.txt
mutt -s "scanned pdf" -- [username]@gmail.com < mail.txt
```

# スキャン結果をメール送信するスクリプト

以下のスクリプトを `/etc/scanbd/scripts/scan.sh` に作成します。
スキャナのボタンを押すと、pdfがメール添付で送られるはずです。

```
#!/bin/sh

set -e
export TMP_DIR=`mktemp -d`

echo 'scanning..'
DATE=$(date "+%Y-%m-%d_%H%M%S")
scanimage --batch --batch-print --resolution 240 --mode Gray --source "ADF Duplex" | tesseract -l jpn -c stream_filelist=true - - pdf > $TMP_DIR/$DATE.pdf

echo 'sending an e-mail'
(echo "scanned at "$DATE > $TMP_DIR/mail.txt
mutt -a $TMP_DIR/$DATE.pdf -s "scanned at home" -- [username]@gmail.com < $TMP_DIR/mail.txt
rm -rf $TMP_DIR
echo 'done') &
```