Raspberry Pi にシャットダウンボタンをつける
コンソールを使わずに運用する場合でも自力でシャットダウンができないと何かと不便なので、スイッチでシャットダウンできるようにしました。
参考にしたサイト
http://raspi.tv/2013/how-to-use-interrupts-with-python-on-the-raspberry-pi-and-rpi-gpio
準備
まず、以下のように対話モードでpythonを実行し、RPi.GPIOのバージョンが0.5.1以上であることを確認します。
% sudo python Python 2.7.3 (default, Jan 13 2013, 11:20:46) [GCC 4.6.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import RPi.GPIO as GPIO >>> GPIO.VERSION '0.5.2a'
サンプルの動作確認
まずは割り込み動作の確認のため、参考サイトのサンプルをそのまま試してみます。
% wget http://raspi.tv/download/interrupt1.py.gz gunzip interrupt1.py.gz
interrupt1.py
#!/usr/bin/env python2.7 # script by Alex Eames http://RasPi.tv/ # http://raspi.tv/2013/how-to-use-interrupts-with-python-on-the-raspberry-pi-and-rpi-gpio import RPi.GPIO as GPIO GPIO.setmode(GPIO.BCM) # GPIO 23 set up as input. It is pulled up to stop false signals GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP) print "Make sure you have a button connected so that when pressed" print "it will connect GPIO port 23 (pin 16) to GND (pin 6)\n" raw_input("Press Enter when ready\n>") print "Waiting for falling edge on port 23" # now the program will do nothing until the signal on port 23 # starts to fall towards zero. This is why we used the pullup # to keep the signal high and prevent a false interrupt print "During this waiting time, your computer is not" print "wasting resources by polling for a button press.\n" print "Press your button when ready to initiate a falling edge interrupt." try: GPIO.wait_for_edge(23, GPIO.FALLING) print "\nFalling edge detected. Now your program can continue with" print "whatever was waiting for a button press." except KeyboardInterrupt: GPIO.cleanup() # clean up GPIO on CTRL+C exit GPIO.cleanup() # clean up GPIO on normal exit
このスクリプトを、rootで起動します。
(pin16とpin6をボタンに繋げと書いてありますが、pin6の代わりにpin14を使用しました。
14と16が隣同士なのでこちらの方がわかりやすいかと)
% sudo ./interrupt1.py Make sure you have a button connected so that when pressed it will connect GPIO port 23 (pin 16) to GND (pin 6) Press Enter when ready > Waiting for falling edge on port 23 During this waiting time, your computer is not wasting resources by polling for a button press. Press your button when ready to initiate a falling edge interrupt. (ここでスイッチを押す) Falling edge detected. Now your program can continue with whatever was waiting for a button press.
スイッチに反応してコマンドが終了します。
スクリプト改造
上記のサンプルを元に、スイッチが押されたらシャットダウンを行うコマンドを作ります。
/usr/local/sbin/shutdown-btn.py
#!/usr/bin/env python2.7 import RPi.GPIO as GPIO import os GPIO.setmode(GPIO.BCM) GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP) try: GPIO.wait_for_edge(23, GPIO.FALLING) except KeyboardInterrupt: GPIO.cleanup() # clean up GPIO on CTRL+C exit GPIO.cleanup() # clean up GPIO on normal exit os.system("/sbin/shutdown -h now")
これをrootで起動し、スイッチを押せばシャットダウンが行われます
sudo /usr/local/sbin/shutdown-btn.py (スイッチを押す) Broadcast message from root@pi2 (pts/1) (Thu Sep 26 01:27:26 2013): The system is going down for system halt NOW!
init script作成
自動で起動したいので、サービス化します。
下記内容で、/etc/init.d/shutdown-button を作成します。
### BEGIN INIT INFO # Provides: shutdown-button # Required-Start: # Required-Stop: # Default-Start: 1 2 3 4 5 6 # Default-Stop: 0 # Short-Description: Shutdown Button # Description: wait Shutdown Button ### END INIT INFO #! /bin/sh # /etc/init.d/shutdown-button PIDFILE=/var/run/shutdown-btn.pid case "$1" in start) if [ -f $PIDFILE ]; then echo $PIDFILE exists. exit 1 fi start-stop-daemon -S -x /usr/local/sbin/shutdown-btn.py -b -m -p $PIDFILE ;; stop) if [ ! -f $PIDFILE ]; then echo $PIDFILE not found. exit 1 fi start-stop-daemon -K -p $PIDFILE rm $PIDFILE ;; *) echo "Usage: /etc/init.d/shutdown-button {start|stop}" exit 1 ;; esac exit 0
update-rc.dでinit scriptを登録します。デフォルトのrunlevel設定と違うと警告が出ますが、これでOKです。
% sudo update-rc.d shutdown-button defaults update-rc.d: using dependency based boot sequencing update-rc.d: warning: default start runlevel arguments (2 3 4 5) do not match shutdown-button Default-Start values (1 2 3 4 5 6) update-rc.d: warning: default stop runlevel arguments (0 1 6) do not match shutdown-button Default-Stop values (0)
これで /usr/local/sbin/shutdown-btn.py が自動で起動されるようになりました。