ラズパイにセンサーを取り付けて温度・湿度を計測し、その結果をメール送信するプログラムを作成しました。
- 準備(温湿度センサー・はんだごての購入)
- はんだづけ
- 回路を繋ぐ
- プログラム作成Ⅰ(smbus)
- プログラム作成Ⅱ(smtplib)
- cronの設定
今回は、5. プログラム作成Ⅱ、6. cronの設定についてです。
前回はセンサーから温度・湿度を取得するところまでコードを記述しました。
今回は
- 得られたデータをメール送信するため、smtplibモジュールを用いてコーディングを進め、プログラムを完成させる
- 完成したプログラムをcronで定期実行させる
プログラムを起動すれば温湿度のデータがメールで送信されます。そのタイミングをcronで制御します。
以前の投稿は下からどうぞ。
プログラム作成Ⅱ
メール本文に記す情報を決める
わたしが個人的に載せたい情報は以下です。
- 計測日時
- 温湿度の計測結果
順番にやっていきます。
計測日時
計測した日付・時刻がメールに表示されていた方がわかりやすいですよね。datetimeモジュールを用いてそれらを取得します。
import datetime
dt = datetime.datetime.today()
dt_list = [
str(dt.year),
str(dt.month),
str(dt.day),
str(dt.hour),
str(dt.minute)]
now = "/".join(dt_list)
年、月、日、時、分を「/」で区切った文字列を作成しました。
例えば、2022/10/4/18/59 のような形式ですね。
計測結果
まず、ただ計測した数値だけが書かれていても、それが何の値なのか判断できないと思うので、データ名を表す文字列を作成します。
次に、前回得た計測結果はそのままだと小数を含みます。そこまで詳細なデータは必要ないので、数値を整数に丸めた後、文字列に変換します。
データ名と計測結果、ふたつの文字列を演算してひとつの文字列にまとめます。例えば、temperature: 29 といった形です。
#温度
temp = "temprature: "
temp += str(int(temperature))
#湿度
humi = "humidity: "
humi += str(int(humidity))
メール送信
先にSMTPの設定を済ませてあります。プロバイダーですが、Googleがわかりやすかったのでgmailを使用しました。
アカウントからアプリパスワードを設定する必要があります。詳しくは「Google アカウント ヘルプ」の「アプリパスワードでログインする」に説明があります。
smtplibモジュールで計測日時・結果を送信します。コーディングは書籍『退屈なことはPythonにやらせよう』を参考にしました。
import smtplib
message = "Subject: Report.\n" + "\n".join([now, temp, humi])
smtp_obj = smtplib.SMTP("smtp.gmail.com", 587)
smtp_obj.ehlo()
smtp_obj.starttls()
smtp_obj.login("送信元アドレス", "パスワード")
smtp_obj.sendmail("送信元アドレス", "送信先アドレス", message)
メール本文はシンプルに計測日時・温度・湿度を改行で区切っただけです。
smtplibモジュールの各関数が返す数値を見て正しくメール送信できているか確認が必要ですが、これはIDLE上で行いました。特に問題はなかったので詳細は割愛します。
cronの設定
crontab -e
から設定をします。
cronの基本的な使い方は『入門者のLinux』を参考にしています。Linuxのコマンドの扱い方について優しく解説されていて、とても勉強になった書籍です。
時間を設定
12分ごとに計測・送信してほしいので
3,15,27,39,51 * * * *
cronの日時設定については「Admin:s Choice」様の「Crontab Quick Reference」が詳しいです。
命令を指定
/usr/bin/python3 /home/pi/ThermoHygroMeter.py
はじめ、こんなケアレスミスをやっていました。
usr/bin/python3 /home/pi/ThermoHygroMeter.py
待てどもラズパイからメールが送られて来ない…。何か見落としていることがあるのだろうか?
色々調べて、設定ファイルを書き換えてログファイルを出力させた結果…
/bin/sh: 1: usr/bin/python3: not found
ルートディレクトリ!先頭の「/」を忘れていただけでした。
ここを修正して
/usr/bin/python3 /home/pi/ThermoHygroMeter.py
まとめると
3,15,27,39,51 * * * * /usr/bin/python3 /home/pi/ThermoHygroMeter.py
すると、初めてラズパイから観測結果のメールが届きました!
まとめ
コード全文です。
#! /usr/bin/python3
# ThermoHygroMeter.py
import smbus
import smtplib
import datetime
#TODO smBusの設定
i2c = smbus.SMBus(1)
address = 0x44
#TODO 単発測定(クロスストレッチ有)
i2c.write_byte_data(address, 0x2C, 0x06)
#TODO データ読み取り
dac = i2c.read_i2c_block_data(address, 0x00, 0x06)
#TODO ビット演算
tmp_temp = dac[0] << 8 | dac[1]
tmp_humi = dac[3] << 8 | dac[4]
#TODO 換算
temperature = -45 + 175 * tmp_temp / (pow(2, 16) -1)
humidity = 100 * tmp_humi / (pow(2, 16) -1)
#TODO 日付と時刻の取得
dt = datetime.datetime.today()
dt_list = [
str(dt.year),
str(dt.month),
str(dt.day),
str(dt.hour),
str(dt.minute)]
now = "/".join(dt_list)
#TODO 文字列化
temp = "temprature: "
temp += str(int(temperature))
humi = "humidity: "
humi += str(int(humidity))
#TODO メール作成
message = "Subject: Report.\n" + "\n".join([now, temp, humi])
#TODO メール送信
smtp_obj = smtplib.SMTP("smtp.gmail.com", 587)
smtp_obj.ehlo()
smtp_obj.starttls()
smtp_obj.login("送信元アドレス", "パスワード")
smtp_obj.sendmail("送信元アドレス", "送信先アドレス", message)
smtp_obj.quit()
終わりに
今回のcron設定及びコードでは、24時間いつでも12分毎にメールが届いてしまいます。なので、実際には上記のコードにif文を加えて
- 真夜中はメール送信しない
- デイタイムは毎時03分には定時送信させる
- 15, 27, 39, 51分は、観測結果を判定し、危険な温度・湿度の時のみ送信
判定結果でそう動作するよう修正しています。
また、ラズパイの発熱に異常があった際、すぐ対応できるようにしたかったので
- Linuxコマンドでcpu温度を取得
- ThermoHygroMeter.pyの引数にcpu温度を指定
- sysモジュールでcpu温度を取得し、異常時にもメール送信
というようにプログラムを変更しています。
2022年10月9日現在、特にトラブルなく計測及びその結果のメール送信を自動で行ってくれています。
たまにメールが来なかったり、送信エラーの通知メールが届いたりしますが、これはおそらくわたしのWi-Fi環境が良くないせいだと思います。ルーターから遠い、障害物が多い、そのあたりが原因だと考えています。
以上です。今回で【RaspberryPiで温湿度計測】は終了です。
読んでくださった方、ありがとうございました。
著者名 | 書籍名 | 出版 | 発行年月日 | 参照頁 |
---|---|---|---|---|
著:Al Sweigart 訳:相川愛三 | 退屈なことはPythonにやらせよう | オライリー・ジャパン | 初版:2017/6/1 第7刷:2020/9/4 | 419~ |
奈佐原顕郎 | 入門者のLinux | 講談社 | 第1刷:2016/10/20 第7刷:2021/7/7 | 295~ |
サイト名 | ページタイトル | URL | 参考にした日付 |
---|---|---|---|
Google アカウント ヘルプ | アプリパスワードでログインする | https://support.google.com/accounts/answer/185833 | 2022/10/8 |
Admin:s Choice | Crontab Quick Reference | https://www.adminschoice.com/crontab-quick-reference | 2022/10/8 |