Raspberry PiによるSOS発報システム その5 ～自動メール送信でハマる

#もくじ
[その1 ～システム概要](https://qiita.com/maitech/items/a1497892c80826c12330)
[その2 ～GPIOを利用したスイッチの状態検知](https://qiita.com/maitech/items/d63a77dea72355f142b5)
[その3 ～アルゴリズム設計](https://qiita.com/maitech/items/f44eb0652fdb268eb9d0)
[その4 ～ハードウェアの準備](https://qiita.com/maitech/items/58a1dc2aab50afe9c5ab)
その5 ～自動メール送信でハマる ←本記事です
[その6 ～キャリアグレードNAT下の端末に外部からSSHでアクセスする](https://qiita.com/maitech/items/b51abd1d78588acf3607)
[その7 ～総括](https://qiita.com/maitech/items/4864a1ddf991f48d728d)

#はじめに
<A HREF=https://qiita.com/maitech/items/58a1dc2aab50afe9c5ab>前回</A>までに，システムのハードウェア・ソフトウェアの仕様を紹介しましたが，いざコーディングを行い自動メール送信を行おうとしたところで少しハマってしまいました。
ここでは，その辺のトラブルを含めて最終的な発報の様子までを紹介していきたいと思います。

#sSMTPとmailutilsによる自動メール送信
Raspberry Piによる自動メール送信についてGoogle先生に尋ねれば，いくつかの解決例をすぐに見つけ出すことができます。何ともありがたいことです。
本システムでは，<A HREF=http://nort-wmli.blogspot.com/2014/12/raspberry-pi-ssmtp.html>こちらの情報[1]</A>を参考にさせていただき，sSMTPとmailutilsを使ってメールを送信することにしました。

##sSMTPのインストールと設定
まずはパッケージをインストール。

```
$ sudo apt install ssmtp
```

続いて設定を行います。
sSMTPの設定ファイルは/etc/ssmtp/ssmtp.confであり，そこに以下のように設定を書き込みました。
私は普段plalaのメールサービスを利用しているため，このシステムでもそのサービスを使うことにしました。

```/etc/ssmtp/ssmtp.conf
root=hoge@hoge.plala.or.jp #自分のメールアドレス
mailhub=hoge.plala.or.jp:465 #SMTPサーバ名とポート番号
hostname=hogehoge #Raspberry Piのホストネーム
AuthUser=hoge@hoge.plala.or.jp #ユーザアカウント名
AuthPass=hogehogehoge #パスワード
AuthLogin=YES
AuthMethod=LOGIN
UseTLS=YES
```

これでsSMTPの設定はひとまず完了です。

##mailutilsを使ったメール送信
こちらもまずはパッケージをインストール。

```
$ sudo apt install mailutils
```

続いてmailコマンドを使ってコマンドラインからテストメールを送信してみます。

```
$ mail hoge@gmail.com
Cc:
Subject:Test.
This is test.
（ここで Ctrl + d を押す：EOF）
```

結果は...素晴らしい！
pi@hogehogeというFromアドレスでGmailにメールが送信できました。
しかし，docomoのキャリアメール宛に送っても届きません...。
imode時代にドメイン指定受信なんてのを設定したような微かな記憶もありましたが，果たしてその設定がspモードにも引き継がれているのか...。
なにはともあれFromアドレスをまともなアドレスに書き換えれば送信できるかもしれないと考え，Fromアドレスを任意のアドレスにする方法を調べました。

##From表記でハマる
Google先生は頼もしいもので，mailutilsでFromアドレスを任意のアドレスにする方法もすぐに<A HREF=http://blog.rutoru.com/2014/04/08/raspberry-pi-ssmtp/>見つかりました[2]</A>。
具体的には以下のようにします。

```
$ mail hoge@docomo.ne.jp -aFrom:hoge@hoge.plala.or.jp
Cc:
Subject:Test.
This is test.
（ここで Ctrl + d を押す：EOF）
```

結果は...ダメでした。
試しにgmailのアカウントに送ってみるとうまくいきましたが，Fromアドレスは「pi@hogehoge」のまま。どうやらFromアドレスがうまく変更できていないようです。困った...。

ここで今一度設定ファイルを見直してみると，以下のコメントを発見しました。

```/etc/ssmtp/ssmtp.conf
# Are users allowed to set their own From: address?
# YES - Allow the user to specify their own From: address
# NO - Use the system generated From: address
#FromLineOverride=YES
```

なるほどこれです。
ユーザーが任意にFromアドレスを設定するには「FromLineOverride=YES」としなければいけないということですね。
というわけで「#FromLineOverride=YES」の頭の#を削除してパラメータを有効化したところ，Fromアドレスの書き換えに成功し，キャリアメールにも送信可能になりました。

めでたしめでたし...と行きたいところでしたが，今度はもう一つの壁が立ちはだかります。

##文字コードでハマる
gmailやPC用のメールクライアント宛に送る場合は，特に文字コードを意識せずとも（UTF-8のまま）日本語メールが送信できましたが，docomoメールやez-webメールでは文字化けしてしまいうまくいきませんでした。
どうやらキャリアメールに日本語メールを送信する際には文字コードをしっかりとISO-2022-JPに変換してから送信しなければいけないようです。
そこで，本システムではiconvコマンドを使って文字コードを変換することにしました。

本システムではメールの本文が書かれたファイルを用意し，そのファイルを読み込んで送信する方式としていますが，例えばC言語で，UTF-8で書かれた本文ファイル「/dev/shm/mailtemp1.txt」を読んで，その文字コードをISO-2022-JPに変換して送信するには以下のようにします。

```
  sprintf(command,"iconv -f UTF-8 -t ISO-2022-JP /dev/shm/mailtemp1.txt | mail -s \'%s\' %s -aFrom:%s",str1,str2,str3);  
  system(command);
```

ここで，commandはコマンド実行用の文字列，str1は主題の文字列，str2は宛先アドレスの文字列，str3はFromアドレスの文字列です。
これでやっとキャリアメールに対して日本語メールを送信できるようになりました。

#実際の発報例
さて，では本システムで実際に発報されるメールの例を紹介します。
##定時発報の例
12時間ごとに以下のようなメールが自動的に送信されます。
<img src="https://i.imgur.com/XSqpbRK.png" width=50%>
本文には，過去12時間の間にトイレのドアが開けられたかどうかと，メール送信時の各スイッチの状態が含まれます。
異常が起ころうが起こるまいが定時発報を行うことにより，システムが動作していることを定期的に確認することができます。
尚，本システムではch.05以降はまだスイッチを接続していないので回路はオープンとなっており，ステータスは1になっています。

##緊急発報の例
こちらはSOSボタンが押された場合に送られるメールの例です。
<img src="https://i.imgur.com/j4jnnDC.png" width=50%>
本文には，SOSボタンが押された場所と，押された時刻および連絡先が含まれます。
連絡先にはボタンが設置されている住宅の住人（私の義母）と私と妻，および義母宅のご近所さんの連絡先が記してあります。
メール受信者はこのメール画面の電話番号をタッチすることですぐに連絡アクションが取れる仕組みです。

続いてこちらはSOSボタンがリセットされた場合に送られるメールの例です。
<img src="https://i.imgur.com/yg2xoi3.png" width=50%>
本システムで使用しているSOSボタンは，一度作動させるとノブを回転させない限り自動的には復帰しない仕様なので，このメールが受信されたということは，ボタン操作者が意思を持ってボタンを復帰させたことを意味し，緊急事態が解消されたことがわかります。
これにより，メール受信者はより落ち着いて次の行動に移れるものと期待しています。

#補足 ～なぜキャリアメールを使うのか～
ここまで読んでこられた方々の中で「今どきわざわざキャリアメールを使う必要なんてないだろう」と思った方は少なくないと思われますので，本システムをキャリアメール宛の発報に対応させた2つの理由について述べたいと思います。

1つ目は，送信から受信までの時間差が短いということです。
どういうわけかわかりませんが，例えばgmailとdocomoメールとでは，docomoメールの方が早くメールが受信されます。
いわゆる「おま環」な気もしないでもないですが，少なくとも私の環境ではdocomoメールよりgmailの方が早く受信できたことはありませんでした。

2つ目は，極力受信者を選ばないためです。
現状ではこのメールの受信者は私と妻であり，いずれもスマホユーザーですので（時間差の問題を除けば）キャリアメールにこだわる必要はありません。
しかしながら，今後本システムの安定稼働が確認されれば，受信者を義母宅のご近所さんに設定することが考えられ，その場合にはガラケーに送信できないと役に立たない可能性が高いのです。

以上の2つの理由から，今回はキャリアメールに日本語メールを送信できることにこだわって開発を行いました。

#次回予告
ここまででSOS発報システムのメイン機能は実現できました。
次回は，キャリアNAT下に置かれている本システムに対していかにしてリモートメンテナンスを行うかについて書いてみたいと思います。

#参考にさせていただいた情報
[1][WM×LI Raspberry Pi から sSMTP でメールを送る．](http://nort-wmli.blogspot.com/2014/12/raspberry-pi-ssmtp.html)
[2][るとるのITぶろぐ Raspberry PiからSSMTPとMailコマンド（mailutils）でメール送信](http://blog.rutoru.com/2014/04/08/raspberry-pi-ssmtp/)