はじめに
RaspberryPiの端子に信号が入力されると、シャットダウンする機能です。
いろいろなサンプルが公開されていますが、ここでは、systemdからスクリプトを起動して、定期的に監視する方法を説明します。
環境
- Raspbian(2018-11-13-raspbian-stretch-lite)
スクリプト
GPIOの監視
「定数」の所は、環境に合わせて修正してください。
定数 | 意味 |
---|---|
SET_WATCH_PORT | GPIOピンにシャットダウン信号を入れる番号を指定 |
SET_TRIGGER | 信号の立ち上がり・立ち下がりどちらで反応するかを設定 |
SET_WATCH_INTERVAL | 指定した秒数ごとに、シャットダウン信号の状態を監視 |
ソース中の所々の[INSTALL DIR]は、お使いの環境に合わせて書き換えてください。
#!/bin/bash #-------------------------------------------------------------------- #UPSの信号監視とシャットダウン #-------------------------------------------------------------------- # #install: # $ sudo ln -s /home/pi/[INSTALL DIR]/setPowerWatcher.service /etc/systemd/system # $ sudo systemctl enable setPowerWatcher.service # $ sudo systemctl start setPowerWatcher.service #-------------------------------------------------------------------- #ref: # # ※必ずbashを使うこと。shは関数の宣言でエラーが出ます # https://yatta47.hateblo.jp/entry/2014/04/20/222707 # #---------------------------------- #定数 #---------------------------------- #監視するポート SET_WATCH_PORT=2 #監視モード # 1:ダウンパルス、0:アップパルス SET_TRIGGER=1 #監視ループの間隔(sec) SET_WATCH_INTERVAL=1 #---------------------------------- #関数 #---------------------------------- #シャットダウンの開始処理 function ShutdownGoProc ( ) { #シャットダウン信号を検出したメッセージを表示 echo " ! Shutdown signal detected. ${MESSAGE}" #シャットダウン処理を開始 if [ ! "$MODE_TEST" = 1 ]; then #瞬停防止のため1秒だけshutdownを待つ /sbin/shutdown -P now fi } #シャットダウンの停止処理 function ShutdownStopProc ( ) { #シャットダウン信号を検出したメッセージを表示 echo " + Shutdown signal disappeared. ${MESSAGE}" #シャットダウン処理を中止 if [ ! "$MODE_TEST" = 1 ]; then /sbin/shutdown -c fi #すぐにループ処理に戻らないよう、ウェイト sleep 1 } #---------------------------------- #メイン処理 #---------------------------------- #実行中ユーザをチェック if [ `/usr/bin/id -u` != "0" ]; then #rootでなければ異常終了 echo " ! Please run as root." exit 1 fi #主要コマンドの存在をチェック if [ ! -x /usr/bin/gpio ]; then #見つからなければ異常終了 echo " ! No 'gpio' Command." exit 1 fi #自身のコマンド名を変数に入れる。usage用 CMDNAME=`basename $0` #引数のチェックと動作フラグの生成 #https://shellscript.sunone.me/parameter.html while getopts vt OPT do case $OPT in "v" ) #verboseモード MODE_VERBOSE=1 ;; "t" ) #テストモード(シャットダウンはしない) MODE_TEST=1 ;; * ) #それ以外の指定は、usageを表示 echo "Usage: $CMDNAME [-v] [-t]" 1>&2 exit 1 ;; esac done #動作モードのメッセージ if [ ${SET_TRIGGER} -eq 1 ]; then MESSAGE="(MODE: Down trigger)" else MESSAGE="(MODE: Up trigger)" fi #起動メッセージ if [ "$MODE_VERBOSE" = 1 ]; then #メッセージ echo " * Monitor the GPIO signal and shutdown * ${MESSAGE}" #テストモードのメッセージ表示 if [ "$MODE_TEST" = 1 ]; then echo ' - test mode (no shutdown)' fi fi #ポートの初期化 `/usr/bin/gpio -g mode ${SET_WATCH_PORT} in` #監視ポートの状態変数の初期化と問い合わせ STAT_PORT_PREV=`/usr/bin/gpio -g read ${SET_WATCH_PORT}` #監視ループ while : do #監視ポートの状態を問い合わせ STAT_PORT_NOW=`/usr/bin/gpio -g read ${SET_WATCH_PORT}` if [ ${SET_TRIGGER} -eq 1 -a ${STAT_PORT_PREV} = "1" -a ${STAT_PORT_NOW} = "0" ]; then #ダウントリガで検知 ShutdownGoProc elif [ ${SET_TRIGGER} -eq 0 -a ${STAT_PORT_PREV} = "0" -a ${STAT_PORT_NOW} = "1" ]; then #アップトリガで検知 ShutdownGoProc elif [ ${SET_TRIGGER} -eq 1 -a ${STAT_PORT_PREV} = "0" -a ${STAT_PORT_NOW} = "1" ]; then #アップトリガで検知 ShutdownStopProc elif [ ${SET_TRIGGER} -eq 0 -a ${STAT_PORT_PREV} = "1" -a ${STAT_PORT_NOW} = "0" ]; then #ダウントリガで検知 ShutdownStopProc fi #監視ポートの状態変数に、現在の状態を代入 STAT_PORT_PREV=${STAT_PORT_NOW} #ウェイト sleep ${SET_WATCH_INTERVAL} done exit 0
systemdに登録するserviceファイル
[Unit] Description=Monitor the GPIO signal and shutdown After=local-fs.target ConditionPathExists=/home/pi/[INSTALL DIR] [Service] ExecStart=/home/pi/[INSTALL DIR]/setPowerWatcher.sh ExecStop=/bin/kill ${MAINPID} Restart=on-failure StartLimitInterval=60 StartLimitBurst=3 KillMode=mixed Type=simple User=root Group=root [Install] WantedBy=multi-user.target
インストール手順
systemdへ登録
systemdに登録して、サービスを起動します。
$ sudo ln -s /home/pi/[INSTALL DIR]/setPowerWatcher.service /etc/systemd/system $ sudo systemctl enable /home/pi/[INSTALL DIR]/setPowerWatcher.service
serviceファイルを修正した時
下記のように都度、リロードします。
$ sudo systemctl daemon-reload
状態を確認
systemctl statusコマンドで、状態を確認します。
まだ起動していません
$ systemctl status setPowerWatcher.service ● setPowerWatcher.service - Monitor the GPIO signal and shutdown Loaded: loaded (/home/pi/[INSTALL DIR]/setPowerWatcher.service; linked; vendor preset: enabled) Active: inactive (dead)
起動
$ sudo systemctl start setPowerWatcher.service
状態を確認
下記のようになっていて、左上の●が緑色になっていれば、正常に起動しています。
$ systemctl status setPowerWatcher.service ● setPowerWatcher.service - Monitor the GPIO signal and shutdown Loaded: loaded (/home/pi/[INSTALL DIR]/setPowerWatcher.service; enabled; vendor preset: enabled) Active: active (running) since Sat 2019-03-09 15:47:22 JST; 9s ago Main PID: 537 (setPowerWatcher) CGroup: /system.slice/setPowerWatcher.service tq537 /bin/bash /home/pi/[INSTALL DIR]/setPowerWatcher.sh mq564 sleep 1 Mar 09 15:47:22 raspizwh systemd[1]: Started Monitor the GPIO signal and shutdown.
動作確認
GPIOに信号を入れると、間もなくシャットダウンします
その際syslogには、下記のメッセージが残ります。
Mar 9 15:58:13 raspizwh setPowerWatcher.sh[537]: ! Shutdown signal detected. (MODE: Down trigger)