画像処理とか機械学習とか

画像処理や機械学習関連の事について気まぐれで書いていきます。歩行者検出関係が多いと思います。ハリネズミもたまに出現します。

Raspberry piで温度管理システムをバックグラウンドで起動できるようにする

前回の記事でRaspberry piの温度管理システムから、メールが送信できるように変更しました。今回は、前回のPythonのプログラムをバックグラウンドで起動させておく方法を紹介します。

Linuxで何かサービスをバックグラウンドで起動させておくにはデーモンという名前の物を使えばいいみたいです。
Pythonのプログラムをデーモン化するには、python-daemonを使いました。

$sudo apt-get install python-daemon

でインストールしてください。

実際に作成したプログラムを以下に載せます。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import serial
import time
import os.path
import datetime
import smtplib
from email import Encoders
from email.Utils import formatdate
from email.MIMEBase import MIMEBase
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
import daemon.runner


#Google account
ADDRESS = "送信元のアカウント"
PASSWARD = "パスワード"

#SMTP Server
SMTP = "smtp.gmail.com"
PORT = 587

def create_message(from_addr, to_addr, subject, body):

    msg = MIMEMultipart()
    msg["From"] = from_addr
    msg["To"] = to_addr
    msg["Date"] = formatdate()
    msg["Subject"] = subject
    body = MIMEText(body)
    msg.attach(body)

    return msg

def send(from_addr, to_addrs, msg):

    smtpobj = smtplib.SMTP(SMTP, PORT)
    smtpobj.ehlo()
    smtpobj.starttls()
    smtpobj.ehlo()
    smtpobj.login(ADDRESS, PASSWARD)
    smtpobj.sendmail(from_addr, to_addrs, msg.as_string())
    smtpobj.close()



class TempDaemon:

        def __init__(self):
            self.stdin_path = self.stdout_path = self.stderr_path = '/dev/null'
            self.pidfile_timeout = 10
            self.directory = os.path.expanduser('~/.test/')
                os.mkdir(self.directory)
            self.pidfile_path = os.path.join(self.directory, 'test.pid')

        def run(self):

            count = 0;
            ser = serial.Serial('/dev/ttyACM0', 9600)
            time.sleep(3)

            while True:
                count = count + 1
                time.sleep(1)
                data = ser.readline()

                if count > 1:
                    data = float(data)
                    to_addr = "送信先アドレス"

                    if data < 18 or data > 30 :
                        #subject and body
                        subject = "温度警告"
                        body = "現在の温度 " + str(data) + "度です。\n温度調節して下さい。"

                        #create message
                        msg = create_message(ADDRESS, to_addr, subject, body)

                        #send
                       send(ADDRESS, [to_addr], msg)

                    elif count%1440 == 0:
                        #4時間ごとに定期報告
                        subject = "ハリネズミ管理システム"
                        body = time.ctime()+"\n現在の温度 " + str(data) + "度です。"

                        #create message
                        msg = create_message(ADDRESS, to_addr, subject, body)

                        #send
                        send(ADDRESS, [to_addr], msg)



def main():
    daemon_runner = daemon.runner.DaemonRunner(TempDaemon())
    daemon_runner.do_action()

if __name__ == '__main__':
    main()

このプログラムでは、温度が18度を下回るか、30度より高くなった場合にあらかじめ設定しておいたメールアドレスに警告メールを送ります。
また、警告メール以外に4時間おきに温度をメールで報告してくれます。

上記コードの以下の部分がデーモンの本体です。

class TempDaemon:

        def __init__(self):
            self.stdin_path = self.stdout_path = self.stderr_path = '/dev/null'
            self.pidfile_timeout = 10
            self.directory = os.path.expanduser('~/.test/')
                os.mkdir(self.directory)
            self.pidfile_path = os.path.join(self.directory, 'test.pid')

        def run(self):
      while True:
       #何か処理を記述

バックグラウンドで起動させるには
./temp.py start

終了させるには
./temp.py stop

を入力すればオッケーです。
これでとりあえずバックグラウンドでの起動が可能となりました。