13
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

RaspberryPi zero WH・LINE API・heroku・Beebotteを使ってエアコンを遠隔操作する【ソフトウェア編】

Last updated at Posted at 2020-04-04

はじめに

自宅のエアコンをLINEから操作するようなシステムを作っていきます.
記事が長くなりそうなので

  1. ラズパイからエアコンを操作できるようにする
  2. LINEからメッセージを送ってエアコンを操作できるようにする

の2つに分けます.適宜必要な箇所を参照していただけると幸いです.
この記事では,2のLINEからメッセージを送り,それを受けてエアコンを制御する部分について説明します.

1のハードウェア部分の構成に関してはこちらです.

環境はWindows10, WSLで行います.


完成形

こんな感じでLINEからエアコンを操作します(クリックするとyoutubeに飛びます).

IMAGE ALT TEXT HERE

システムのフロー図を次に示します.

2020-04-03_18h18_54.png
操作はLINEから行うことができるので,出先のスマホからや研究室のPCなどから操作できます.

LINE APIからはWebhookが飛ばされ,それをHeroku上に立てたwebサーバがキャッチし,mqttを通してラズパイに知らせます.

ラズパイでは,赤外LEDを制御し,あらかじめ記録しておいたエアコンの信号を再生することでエアコンを制御するという形になっています.
IMG_4539.PNG
LINEの画面はこのようになっていて,リッチメニューで操作できます.
また,センサを使用してエアコンが点灯したかどうかを確認できるようになっています.


本編の概要

本編は,

  1. LINE Botの作成
  2. HerokuとBeeboteの準備
  3. Heroku上にWebサーバをデプロイする
  4. ラズパイ上で動作させるプログラムの説明
  5. 動作確認
  6. 付録

という構成になっています.


LINE Botの作成

LINEのMessaging APIを使用して今回のシステムで操作の受け付け・結果表示を行うLINEのボットを作成します.
こちらのサイトを参考にして,LINE Developersへの登録・チャネルの作成を行ってください.

aircon_control」と適当に名前をつけてこのようにボットが作成できたら完了です.

2020-04-01_08h03_13.png

次に友達登録を行います.チャネルの管理画面から,Messaging APIをクリックし,QR codeを使用して友達登録を行ってください.

2020-04-01_08h09_48.png

また次の画面を参考に「Auto-reply message」と「Greeting message」をDisabledに設定し,「Issue」ボタンを押してチャネルアクセストークンを発行します.

2020-04-01_08h46_47.png

今後必要になってくる情報は以下の2つです.

  • Channel secret
  • Channel access token

こちらの情報は,先程のチャネルの管理画面から参照することができるので,必要になったらこのページにきてコピーしてください.


HerokuとBeeboteの準備

Herokuのセットアップ

Heroku とは

こちらのサイトがわかりやすいです.

HerokuとはPaaSと呼ばれるWEBアプリケーションを簡単にホスティングできるサービスです.
初めからネットワークなどのインフラやOSなどのプラットフォームが整っている状態なので,ユーザはソースを書いてアップロードするだけで勝手にデプロイしてくれます.

登録

まずこちらからHerokuの登録を行ってください.

2020-04-01_09h36_25.png

Heroku CLIのインストール

今回はWSL上にHeroku CLI(コマンドラインからHerokuを操作するもの)をインストールしたいと思います.

WSLのインストールはこちらを参照してください.バージョン1で大丈夫です.

Heroku CLIのインストールはこちらのサイトを参考にしました.
下記コマンドをWSL上で実行してください.

$ curl https://cli-assets.heroku.com/install.sh | sh

次のコマンドでHerokuにログインできたら成功です(ブラウザが立ち上がってログインするとターミナル上でもログインが完了します).

$ heroku login

アプリの登録

適当にアプリケーションの名前をつけてアプリを作成します.
この名前がURLに組み込まれるので,他の人と被ると使えません.

なので汎用的な名前(testなど)はもう使われているので適当に探しましょう.また_(アンダーバー)は使えないので-(ハイフン)で代替します.

$ heroku create {アプリ名}

あるいはHerokuの管理画面からもアプリの作成が行なえます.

2020-04-01_12h18_39.png

Beebotteのセットアップ

登録

こちらのサイトへ行ってBeebotteへの登録を行います.

2020-04-03_18h37_00.png

新規チャネルの作成

登録が終わったら管理画面に行き,新規チャネルの登録を行います.
Create Newをクリックします.

2020-04-03_16h23_09.png

次の画面で名前等を設定します.

2020-04-03_16h25_19.png

今回は,

設定
Channel Name my_home
Resource name aircon_control

と設定しました.ここは何でも大丈夫です.
ここの値がmqttのトピック名(my_home/aircon_control)のように設定されます.

トークンの取得

管理画面から先程作成したChannelをクリックするとChannel Token(下図のtoken_*の部分)を得ることが出来ます.

2020-04-03_18h48_44.png


Webサーバをデプロイする

LINEのMessaging APIから送信されるwebhookを受け取るwebサーバを作成します.

環境変数を設定する

まずトークンなどをHerokuの内部の環境変数として定義します.
トークンの悪用などを防ぐ目的なので必ず行いましょう.

まずLINE API関係です.

$ heroku config:set YOUR_CHANNEL_SECRET="Channel Secretの文字列" --app {アプリ名}
$ heroku config:set YOUR_CHANNEL_ACCESS_TOKEN="Access tokenの文字列" --app {アプリ名}

Channel SecretAccess tokenに関しては先程のLINEBotの管理画面から参照してください.

次にBeebotte関係です.

$ heroku config:set YOUR_BEEBOTTE_TOKEN="tokenの文字列(token_*の形)" --app {アプリ名}

先程取得したトークンを入力します.

必要なファイルを用意する

必要なファイルはこの5つです.

ファイル名 役割
main.py ソースコード
runtime.txt Pythonのバージョンを記載
requirements.txt インストールするライブラリとそのバージョンを記載
Procfile プログラムの実行方法を定義
mqtt.beebotte.com.pem Beebotteのサーバにアクセスするための証明書.こちらからダウンロード.

適当にディレクトリを作成し,以下の内容をコピーしてファイルを作成してください.
ファイル名を間違えると怒られるので気をつけてください.

runtime.txt
python-3.7.0
requirements.txt
Flask==1.0.2
line-bot-sdk==1.16.0
paho-mqtt==1.5.0
Procfile
web: python main.py

main.pyに関しては少し長いので次をクリックして見てください.

クリックして展開
main.py
from flask import Flask, request, abort
import paho.mqtt.publish as publish
import os
import json

from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage,
)

app = Flask(__name__)

# LINE API関係の設定値取得
YOUR_CHANNEL_ACCESS_TOKEN = os.environ['YOUR_CHANNEL_ACCESS_TOKEN']
YOUR_CHANNEL_SECRET = os.environ['YOUR_CHANNEL_SECRET']

# Beebotte関係の設定値取得
YOUR_BEEBOTTE_TOKEN = os.environ['YOUR_BEEBOTTE_TOKEN']

line_bot_api = LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(YOUR_CHANNEL_SECRET)

# 動作を起こすメッセージのリスト
on_msg = [s.encode('utf-8') for s in ['on', 'エアコンつけて!']]
off_msg = [s.encode('utf-8') for s in ['off', 'エアコン切って!']]

# LINEに通知メッセージを送る
def broadcast_line_msg(msg):
    line_bot_api.broadcast(TextSendMessage(text=msg))

# エアコン制御用のMQTTをパブリッシュする
def publish_aircon_control_msg(msg):
    publish.single('my_home/aircon_control', \
                    msg, \
                    hostname='mqtt.beebotte.com', \
                    port=8883, \
                    auth = {'username':'token:{}'.format(YOUR_BEEBOTTE_TOKEN)}, \
                    tls={'ca_certs':'mqtt.beebotte.com.pem'})

@app.route('/callback', methods=['POST'])
def callback():
    # get X-Line-Signature header value
    signature = request.headers['X-Line-Signature']

    # get request body as text
    body = request.get_data(as_text=True)
    app.logger.info('Request body: ' + body)

    # handle webhook body
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)

    return 'OK'

@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    msg = event.message.text.encode('utf-8')

    if msg in on_msg:
        publish_aircon_control_msg('on')
    elif msg in off_msg:
        publish_aircon_control_msg('off')
    else:
        broadcast_line_msg('\n'.join(['エアコンをつけたい時:', \
                                     *['['+s.decode('utf-8')+']' for s in on_msg], \
                                     '\nエアコンを消したい時:', \
                                     *['['+s.decode('utf-8')+']' for s in off_msg] , \
                                     '\nって話しかけてね!']))

if __name__ == '__main__':
    port = int(os.getenv('PORT'))
    app.run(host='0.0.0.0', port=port)

main.pyの説明

以下,main.pyの簡単な説明です.

# LINE API関係の設定
YOUR_CHANNEL_ACCESS_TOKEN = os.environ['YOUR_CHANNEL_ACCESS_TOKEN']
YOUR_CHANNEL_SECRET = os.environ['YOUR_CHANNEL_SECRET']

# Beebotte関係の設定
YOUR_BEEBOTTE_TOKEN = os.environ['YOUR_BEEBOTTE_TOKEN']

先程環境変数として設定したLINE APIやBeebotteのトークンを取得しています

# 動作を起こすメッセージのリスト
on_msg = [s.encode('utf-8') for s in ['on', 'エアコンつけて!']]
off_msg = [s.encode('utf-8') for s in ['off', 'エアコン切って!']]

LINEから受け取ったメッセージのうち,どのフレーズでon/off動作を行うか設定します.
日本語の処理が面倒なので,一旦すべてUTF-8にエンコードして扱います.

# エアコン制御用のMQTTをパブリッシュする
def publish_aircon_control_msg(msg):
    publish.single('my_home/aircon_control', \
                    msg, \
                    hostname='mqtt.beebotte.com', \
                    port=8883, \
                    auth = {'username':'token:{}'.format(YOUR_BEEBOTTE_TOKEN)}, \
                    tls={'ca_certs':'mqtt.beebotte.com.pem'})

publish_aircon_control_msg関数ではmsgを受け取ってそれをpayloadとしてパブリッシュします.
mqttのパブリッシュにはpaho.mqttののPublishクラスを使用します.リファレンスはこちらです.

@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    msg = event.message.text.encode('utf-8')

    if msg in on_msg:
        publish_aircon_control_msg('on')
    elif msg in off_msg:
        publish_aircon_control_msg('off')
    else:
        broadcast_line_msg('\n'.join(['エアコンをつけたい時:', \
                                     *['['+s.decode('utf-8')+']' for s in on_msg], \
                                     '\nエアコンを消したい時:', \
                                     *['['+s.decode('utf-8')+']' for s in off_msg] , \
                                     '\nって話しかけてね!']))

LINEからのwebhookの署名が正しい場合にこちらのハンドラが実行されます.
on/offメッセージを判断し,mqttをパブリッシュします.それ以外のメッセージの場合,反応するメッセージのリストを示すようになっています.

2020-04-03_19h35_12.png

表示はこんな感じです.

デプロイを行う

HerokuではアプリのソースをGitレポジトリとして管理するので,ローカルでGitレポジトリを構成します.

対象のディレクトリで移動し,次のコマンドを実行します.

$ git init

ここで

*** Please tell me who you are.

Run

  git config --global user.email "you@example.com"
  git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

などと出たらgitの初期設定を行っていないので指示に従って設定を済ませます.

リモートレポジトリにherokuのレポジトリを指定します.

$ heroku git:remote -a {アプリ名}

次に各ファイルを追跡対象に加えコミットします.

$ git add .
$ git commit -m "Initial commit"

最後にプッシュします.こちらはHerokuにログインした状態で行ってください.

$ git push heroku master

これでエラーログなどが出なければデプロイ成功です.

LINE APIでWebhookの設定を行う

LINE APIの管理画面からWebhookの設定を行います.
Webhook URLに,

https://{アプリ名}.herokuapp.com/callback

と設定してVerifyします.

2020-04-01_21h48_00.png

以上でLINE->Heroku->Beebotteの通路が完成しました.


ラズパイ上で動作させるプログラム

次にPublishされたmqttをSubscribeして赤外LEDを制御するラズパイ側のプログラムを説明します.

ライブラリのインストール

まずpip3からインストールします.Raspbianでは最初から入っていないため,手動でインストールする必要があります.

こちらのサイトを参考にしました.

$ sudo apt-get -y install python3-dev
$ sudo apt-get -y install python3-pip

インストールされたか確認します.

$ pip3 --version

バージョン情報が出てきたら成功です.

次に必要なライブラリをインストールします.

$ pip3 install paho-mqtt
$ pip3 install line-bot-sdk

証明書のダウンロード

こちらからmqtt.beebotte.com.pemをダウンロードして,同ディレクトリに置いてください.

プログラム本体

クリックして展開
mqtt_aircon_control.py
import subprocess
import paho.mqtt.client as mqtt     # MQTTのライブラリをインポート
import datetime
from linebot import LineBotApi
from linebot.models import TextSendMessage
from linebot.exceptions import LineBotApiError

# LINEでメッセージを送信
def send_line_msg(msg):
    line_bot_api = LineBotApi({LINEのアクセストークンの文字列})
    line_bot_api.broadcast(TextSendMessage(text=msg))

# ブローカーに接続できたときの処理
def on_connect(client, userdata, flag, rc):
    print('[mqtt_aircon_control.py] Connected with result code ' + str(rc))  # 接続できた旨表示
    client.subscribe('my_home/aircon_control')  # subするトピックを設定 

# ブローカーが切断したときの処理
def on_disconnect(client, userdata, flag, rc):
    if  rc != 0:
        print('[mqtt_aircon_control.py] Unexpected disconnection.')

# メッセージが届いたときの処理
def on_message(client, userdata, msg):
    # エアコンの信号データのパスを指定
    stop_log_path = '/home/pi/ws/send_data/stop.log'
    heater_log_path = '/home/pi/ws/send_data/heater.log'
    cooler_log_path = '/home/pi/ws/send_data/cooler.log'
    # プログラムの実行ファイルのパスを指定
    exec_send_command = '/home/pi/ws/send'
    exec_switching_verify_command = '/home/pi/ws/switching_verify'

    # メッセージ受け取り
    get_msg = msg.payload.decode('utf-8')

    # 現在日時を取得し,送信するデータファイルを決定する
    dt_now = datetime.datetime.now()
    print('[mqtt_aircon_control.py] Get aircon_control topic(msg:{}) [{}]'.format(get_msg, dt_now.strftime('%Y/%m/%d %H:%M:%S')))
    if 11 <= int(dt_now.strftime('%m')) or int(dt_now.strftime('%m')) <= 4:
        send_data_file = heater_log_path
    else:
        send_data_file = cooler_log_path

    # 信号送信処理
    if get_msg == 'on':
        send_line_msg('エアコンの電源を入れるよ!')
        for i in range(3):
            subprocess.run(['sudo', exec_send_command, send_data_file])
            ret = subprocess.run([exec_switching_verify_command , '10'])
            try:
                if ret.returncode == 0:
                    print('[mqtt_aircon_control.py] Switching successed.')
                    send_line_msg('エアコンの起動を確認したよ!')
                    break
            except:
                print('[mqtt_aircon_control.py] Switching failed.')
                continue
    elif get_msg == 'off':
        send_line_msg('エアコンの電源を消すよ!')
        subprocess.run(['sudo', exec_send_command, stop_log_path])

# MQTTの接続設定
client = mqtt.Client()                 # クラスのインスタンス(実体)の作成
client.on_connect = on_connect         # 接続時のコールバック関数を登録
client.on_disconnect = on_disconnect   # 切断時のコールバックを登録
client.on_message = on_message         # メッセージ到着時のコールバック
 
client.username_pw_set("token:{Beebotteのチャネルトークン(token_*の形)}") 
client.tls_set("/home/pi/ws/mqtt.beebotte.com.pem")
client.connect("mqtt.beebotte.com", 8883, 60)

send_line_msg('システムを起動するよ!')

client.loop_forever()                  # 永久ループして待ち続ける

プログラムの説明

上記のプログラムの簡単な説明を行います.

send_line_msg()
# LINEでメッセージを送信
def send_line_msg(msg):
    line_bot_api = LineBotApi({LINEのアクセストークンの文字列})
    line_bot_api.broadcast(TextSendMessage(text=msg))

send_line_msg関数では,引数に文字列を受け取り,それをLINEの登録している友達に送信します.{LINEのアクセストークンの文字列}には自分のLINEBotのアクセストークンを記入します.

on_massage()
# メッセージが届いたときの処理
def on_message(client, userdata, msg):
    # エアコンの信号データのパスを指定
    stop_log_path = '/home/pi/ws/send_data/stop.log'
    heater_log_path = '/home/pi/ws/send_data/heater.log'
    cooler_log_path = '/home/pi/ws/send_data/cooler.log'
    # プログラムの実行ファイルのパスを指定
    exec_send_path = '/home/pi/ws/send'
    exec_switching_verify_path = '/home/pi/ws/switching_verify'

    # メッセージ受け取り
    get_msg = msg.payload.decode('utf-8')

    # 現在日時を取得し,送信するデータファイルを決定する
    dt_now = datetime.datetime.now()
    print('[mqtt_aircon_control.py] Get aircon_control topic(msg:{}) [{}]'.format(get_msg, dt_now.strftime('%Y/%m/%d %H:%M:%S')))
    if 11 <= int(dt_now.strftime('%m')) or int(dt_now.strftime('%m')) <= 5:
        send_data_file = heater_log_path
    else:
        send_data_file = cooler_log_path

    # 信号送信処理
    if get_msg == 'on':
        send_line_msg('エアコンの電源を入れるよ!')
        for i in range(3):
            subprocess.run(['sudo', exec_send_path, send_data_file])
            ret = subprocess.run([exec_switching_verify_path , '10'])
            try:
                if ret.returncode == 0:
                    print('[mqtt_aircon_control.py] Switching successed.')
                    send_line_msg('エアコンの起動を確認したよ!')
                    break
            except:
                print('[mqtt_aircon_control.py] Switching failed.')
                continue
    elif get_msg == 'off':
        send_line_msg('エアコンの電源を消すよ!')
        subprocess.run(['sudo', exec_send_path, stop_log_path])

on_message関数は,pahoのmqttクライアントがサブスクライブしているトピックのメッセージを受信した際に実行される関数です.

処理内容は,まずメッセージを受け取りonoffを判別します.
onの場合,11月から4月なら暖房,それ以外なら冷房の信号を送信します.
offの場合は,そのままstop信号を送信します.

ユーザが環境によって変えるところは,信号のログファイル(ハードウェア編で作成したstop.logなど)と,送信プログラム起動確認用プログラムの実行ファイルのパスです.

main
# MQTTの接続設定
client = mqtt.Client()                 # クラスのインスタンス(実体)の作成
client.on_connect = on_connect         # 接続時のコールバック関数を登録
client.on_disconnect = on_disconnect   # 切断時のコールバックを登録
client.on_message = on_message         # メッセージ到着時のコールバック
 
client.username_pw_set("token:{Beebotteのチャネルトークン(token_*の形)}") 
client.tls_set("/home/pi/ws/mqtt.beebotte.com.pem")
client.connect("mqtt.beebotte.com", 8883, 60)

send_line_msg('システムを起動するよ!')

client.loop_forever()                  # 永久ループして待ち続ける

main関数がないので,スクリプトを実行したらこのコードが実行されます.
client.tls_setにはサーバ証明書(mqtt.beebotte.com.pem)のフルパスを指定します.

電源を入れた時にプログラムを自動起動

電源を入れる度に先程のpyファイルを実行するのは面倒くさいので,ラズパイが起動したら際にプログラムも自動で起動するようにします.

自動起動にはいくつか方法がありますが今回はsystemdを使用します.
こちらの記事を参考にしました.

*.serviceに指定する実行するシェルスクリプトだけ示します(記事中のautoexec.shに該当するもの).

aircon_control.sh
#!/bin/sh

/usr/bin/python3 -u /home/pi/ws/mqtt_aircon_control.py >> /home/pi/ws/aircon_control.log 2>&1

/usr/bin/python3はフルパスを指定する必要があります.

-uは標準出力のバッファリングを無効にします.実行中の出力などをファイルに書き出したいため,このオプションを指定します.

/home/pi/ws/mqtt_aircon_control.pyは先程作成したpythonスクリプトです.

>> /home/pi/ws/aircon_control.log 2>&1はスクリプトの出力をファイルにリダイレクトします.ここではpythonスクリプトと同ディレクトリに追記で出力するようにしています.


動作確認&最後に

以上で作業は完了になります.
onoffとメッセージを送ることでラズパイが動作し,エアコンが制御できるようになりましたか?

上手くいかない場合はデバッグを行うことになります.
以下のコマンドでherokuのログを確認したり,デバッグプリントを入れたりして地道に原因を突き止めましょう.

$ heroku logs --tail

デバッグは辛いときも多いですがその分動作したときの喜びも一入です.
頑張ってください.

なにか分からないことがあればコメントで対応します.

ちなみに当初はCloudMQTTを使用してこちらの記事を書いていました.
ですが,無料プランが使用できなくなるとのことで急遽Beebotteを使う仕様に変更しました.なので,Beebotteならこうした方がいいよ等あるかもしれませんがその時ははコメントで教えて下さい.
CloudMQTTの方が手軽だったので残念でした.

最後に,ハードウェア編もよろしくお願いします.



付録A.LINE botにリッチメニューを実装する

LINE APIを使用してリッチメニューから操作できるようにします.
Messaging APIのリッチメニューに関してはこちらを参照してください.

IMG_4539.PNG

リッチメニューを登録する順番は,

  1. リッチメニューオブジェクトをボディにしたリクエストをだし,richMenuIdを取得する.
  2. 画像をアップロードする
  3. デフォルトのリッチメニューとして登録する

という感じです.これを自動で行うpythonスクリプトを作成したのでそれを利用してください.

まず,画像編集ソフトを使用してリッチメニューにアップする画像を作成します.
自分が作成した画像も一応上げておきます.

2020-04-03_21h26_32.png

次に下記のスクリプトを使用してリッチメニューの登録を行います.

クリックして展開
richmenu.py
import requests

url = 'https://api.line.me/v2/bot/richmenu'
access_token={channel access token}
img_path = 'rich_menu_simple.png'
send_data='''{
"size":{
    "width":2500,
    "height":843
},
"selected": true,
"name": "LINE Developers Info",
"chatBarText": "Tap to open",
"areas": [
    {
        "bounds": {
            "x": 0,
            "y": 0,
            "width": 1250,
            "height": 843
        },
        "action": {
        "type": "message",
        "label": "on",
        "text": "エアコンつけて!"
        }
    },
    {
        "bounds": {
            "x": 1250,
            "y": 0,
            "width": 1250,
            "height": 843
        },
        "action": {
        "type": "message",
        "label": "off",
        "text": "エアコン切って!"
        }
    }
]
}'''

header = {'Authorization': 'Bearer {}'.format(access_token)}
res = requests.post(url, headers={**header, **{'Content-Type': 'application/json'}}, data=send_data.encode("utf-8"), verify=True).json()

update_url = 'https://api.line.me/v2/bot/richmenu/{}/content'.format(res['richMenuId'])
img_file = open(img_path, "rb")
update_res = requests.post(update_url, headers={**header, **{'Content-Type': 'image/jpeg'}}, data=img_file, verify=True).json()

if update_res:
    print('[ERROR] ', update_res)
    exit()

apply_url = 'https://api.line.me/v2/bot/user/all/richmenu/{}'.format(res['richMenuId'])
apply_res = requests.post(apply_url, headers=header, verify=True).json()

if apply_res:
    print('[ERROR] ', apply_res)
    exit()

print('[SUCCESS] Rich menu image update!')

使用する場合はaccess_tokenimg_pathsend_dataを編集します.
send_dataに関しては先程のリンクを参考にしてください.

実行してSUCCESSが表示されたら成功です.

リッチメニューを押すことで特定のメッセージが送信される仕組みになっています(その後はいままでの処理と同じ).

付録B.Heroku上のアプリを24時間起動させる

通常,HerokuにデプロイしたWebアプリは30分間アクセスがないと自動で停止し,次にアクセスが起こった時にまた起動します.
この起動に時間がかかるため,できるだけ起動したままの状態を保持したいです.

今回はcronを使用して定期的にサーバにリクエストを送ることで停止するのを防ぎます.

以下のコマンドで設定します.

$ crontab -e

エディタが開いたらファイルの最後に以下を追記します.
20分ごとにリクエストをだし,出力は捨てるようになっています.

*/20 * * * * curl https://{アプリ名}.herokuapp.com/ > /dev/null 2>&1

正常に動作しているかの確認はherokuのログを見ることで確認できます.
次のコマンドでログを見てみましょう.

$ heroku logs --tail

Herokuの無料プランの枠は一月あたり1000時間なので,1つのアプリを運用することは問題ありあませんが,2つ以上はこれを超過してしまうため気をつけましょう.

13
18
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?