slee-Pi2 PlusでRaspberry piの電源が落ちた際の復旧を自動化(キャパシタ編)


概要

以前、slee-Pi2 Plusとリレー付き電源で簡易UPSの記事を書いた前後にMechatrax社からキャパシタ基板を開発中との連絡があり、その基板が届いたので、評価も兼ねて使ってみた。

仕組み

以前のリレー付き電源の代わりに、キャパシタ(コンデンサー)を持つ基板からsleePi2 Plusへ電源を供給し、電源断時はそのキャパシタからの電源でraspberry piのshutdown処理を行う。

必要なもの

  • raspberry pi 4 model B w/ Rasbian buster lite 2019-09-26 もしくは 3B
  • slee-Pi2Plus 左が今回入手したキャパシタ基板、右がraspberry pi 4にスタックしたsleePi2 Plus
  • キャパシタ基板
  • スイッチ付きテーブル・タップ

セットアップ

Raspberry pi、slee-Pi2 Plus、キャパシタ基板、電源を接続し、Rasbianの設定を中級編で言及したansible playbookでセットアップします。

キャパシタ基板の接続

キャパシタ基板からは3組のコードが出ている。言われるままに赤と黄をsleePi-2 Plusの電源コネクターへ、グレーを外部入力コネクター(CN3)へ接続します。
そして、キャパシタ基板の空いている端子にACアダプタから電源を接続します。

電圧確認

中級編と同様にMackeelでキャパシタ電圧を測定しようとしたけど、容量の限界とMackerelのpostタイミングが合わなかったので、仕方なく以下のようにbashコマンドで計測。その途中で電源断します。
ちなみに、キャパシタのフル充電は30min程度とのこと。

~# while :; do date; sleepi2ctl -g voltage; sleep 1s; done
Sun  1 Mar 20:45:12 JST 2020
12008
Sun  1 Mar 20:45:13 JST 2020
12008
Sun  1 Mar 20:45:14 JST 2020
12000
Sun  1 Mar 20:45:15 JST 2020
12008
Sun  1 Mar 20:45:17 JST 2020
12000
Sun  1 Mar 20:45:18 JST 2020
7432
Sun  1 Mar 20:45:19 JST 2020
7432
Sun  1 Mar 20:45:20 JST 2020
7432
Sun  1 Mar 20:45:21 JST 2020
7432
Sun  1 Mar 20:45:22 JST 2020
7432
Sun  1 Mar 20:45:23 JST 2020
7448
Sun  1 Mar 20:45:25 JST 2020
7432
Sun  1 Mar 20:45:26 JST 2020
7432
Sun  1 Mar 20:45:27 JST 2020
7448
Sun  1 Mar 20:45:28 JST 2020
7440
Sun  1 Mar 20:45:29 JST 2020
7432
Sun  1 Mar 20:45:30 JST 2020
7440
Sun  1 Mar 20:45:31 JST 2020
7432
Sun  1 Mar 20:45:33 JST 2020
7432
Sun  1 Mar 20:45:34 JST 2020
7432
Sun  1 Mar 20:45:35 JST 2020
7448
Sun  1 Mar 20:45:36 JST 2020
7440
Sun  1 Mar 20:45:37 JST 2020
7432
Sun  1 Mar 20:45:38 JST 2020
7432
Sun  1 Mar 20:45:39 JST 2020
7432
Sun  1 Mar 20:45:41 JST 2020
7464
Sun  1 Mar 20:45:42 JST 2020
7456
Sun  1 Mar 20:45:43 JST 2020
7432
Sun  1 Mar 20:45:44 JST 2020
7432
Sun  1 Mar 20:45:45 JST 2020
7440
Sun  1 Mar 20:45:46 JST 2020
7440
Sun  1 Mar 20:45:47 JST 2020
7448
Sun  1 Mar 20:45:49 JST 2020
7440
Sun  1 Mar 20:45:50 JST 2020
7448
Sun  1 Mar 20:45:51 JST 2020
7440
Sun  1 Mar 20:45:52 JST 2020
7432
Sun  1 Mar 20:45:53 JST 2020
7432
Sun  1 Mar 20:45:54 JST 2020
7440
Sun  1 Mar 20:45:55 JST 2020
7448
Sun  1 Mar 20:45:57 JST 2020
7448
Sun  1 Mar 20:45:58 JST 2020
7440
Sun  1 Mar 20:45:59 JST 2020
7432
Sun  1 Mar 20:46:00 JST 2020
7432
Sun  1 Mar 20:46:01 JST 2020
7448
Sun  1 Mar 20:46:02 JST 2020
7440
Sun  1 Mar 20:46:03 JST 2020
7456
Sun  1 Mar 20:46:05 JST 2020
7432
Sun  1 Mar 20:46:06 JST 2020
7448
Sun  1 Mar 20:46:07 JST 2020
7456
Sun  1 Mar 20:46:08 JST 2020
7448
Sun  1 Mar 20:46:09 JST 2020
7448
Sun  1 Mar 20:46:10 JST 2020
7440
Sun  1 Mar 20:46:11 JST 2020
7448
Sun  1 Mar 20:46:12 JST 2020
7440
Sun  1 Mar 20:46:14 JST 2020
7424
Sun  1 Mar 20:46:15 JST 2020
7424
Sun  1 Mar 20:46:16 JST 2020
7456
Sun  1 Mar 20:46:17 JST 2020
7448
Sun  1 Mar 20:46:18 JST 2020
7432
Sun  1 Mar 20:46:19 JST 2020
7440
Sun  1 Mar 20:46:20 JST 2020
7448
Sun  1 Mar 20:46:22 JST 2020
7448
Sun  1 Mar 20:46:23 JST 2020
7440
Sun  1 Mar 20:46:24 JST 2020
7448
Sun  1 Mar 20:46:25 JST 2020
7440
Sun  1 Mar 20:46:26 JST 2020
7448
Sun  1 Mar 20:46:27 JST 2020
7464
Sun  1 Mar 20:46:28 JST 2020
7472
Sun  1 Mar 20:46:30 JST 2020
7440
Sun  1 Mar 20:46:31 JST 2020
7448
Sun  1 Mar 20:46:32 JST 2020
7440
Sun  1 Mar 20:46:33 JST 2020
7448
Sun  1 Mar 20:46:34 JST 2020
7448
Sun  1 Mar 20:46:35 JST 2020
7456
Sun  1 Mar 20:46:36 JST 2020
7448
Sun  1 Mar 20:46:38 JST 2020
7432
Sun  1 Mar 20:46:39 JST 2020
7440
Sun  1 Mar 20:46:40 JST 2020
7456
Sun  1 Mar 20:46:41 JST 2020
7432
Sun  1 Mar 20:46:42 JST 2020
7456
Sun  1 Mar 20:46:43 JST 2020
7456
Sun  1 Mar 20:46:45 JST 2020
7464
Sun  1 Mar 20:46:46 JST 2020
7448
Sun  1 Mar 20:46:47 JST 2020
7448
Sun  1 Mar 20:46:48 JST 2020
7432
Sun  1 Mar 20:46:49 JST 2020
7448
Sun  1 Mar 20:46:50 JST 2020
7440
Sun  1 Mar 20:46:51 JST 2020
7448
Sun  1 Mar 20:46:52 JST 2020
7432
Sun  1 Mar 20:46:54 JST 2020
7440
Sun  1 Mar 20:46:55 JST 2020
7448
Sun  1 Mar 20:46:56 JST 2020
packet_write_wait: Connection to 192.168.3.10 port 22: Broken pipe

この結果、電源断するとキャパシタ電源に切り替わり、1min30secぐらい7v程度で頑張っていることが分かります。

実働テスト

そこで、sleepi2-monitorでのvoltage監視値を8V=8000mVにしてみる。

/etc/sleepi2-monitor.conf
[voltage]
command = "shutdown -h now"
oneshot = true
threshold = 8000 
  • sleepi2-monitor.serviceのrestartもしくはshutdown -r nowで新しいthresholdが有効になります。

  • 再起動後、キャパシタに十分な電荷が貯まったと思しき頃、電源断!

  • slee-Pi2 Plusまたraspberry piのpower offを確認したら、電源復帰してみると、ちゃんと再起動します。

さらに、

  • 再起動後、キャパシタに十分な電荷が貯まったと思しき頃、電源断!

  • raspberry piのpower off前のshutdown処理中に、電源復帰してみると、このケースでは再起動しませんでした。

このままではshutdown処理中の電源復帰では再起動しないので、以下のコマンドでslee-Pi2 Plusの挙動を変えてみる。

~# sleepi2ctl -s extin-trigger 1 #外部入力の起動トリガをレベル検出に
~# sleepi2ctl -s wakeup-delay 0 #スリープ復帰後にウォッチドッグタイマは動作を開始

この設定後、同様にテストすると、shutdown処理中に電源断しても、shutdown後に再起動するようになります。

この結果、
shutdown処理中に電源断->次の起動でwakeup-flag=watchdog
shutdown後に電源断->次の起動でwakeup-flag=extin
になります。

このあたりの処理を行うスクリプトは前述のplaybookを利用すると、
/opt/mechatrax/etc/ups_shutdownに配置されますので、

# this scrip should be invoked by sleepi2monitor, when sleepi2 Plus works as an ups
/opt/mechatrax/bin/startstop post "shutting down by POWER OFF:Vol.=`sleepi2ctl -g voltage` mV"
sleepi2ctl -s extin-trigger 1
sleepi2ctl -s wakeup-delay 0
shutdown -h now

以下のように

/etc/sleepi2-monitor.conf
[voltage]
command = "/opt/mechatrax/etc/ups_shutdown"

指定すればOKです。このスクリプトをshutdown時に実行されるようにすることは非推奨です。
通常のshutdownプロセスでも実行されると、watchdogが有効になり、shutdownしても再びそのまま再起動するでしょう。

なお、sleepi2ctlで指定した設定値は、再起動によりデフォルトに戻ります。

まとめ

  • ansible playbookでセットアップします。

  • キャパシタの電圧を測定して、適切なthresholdを/etc/sleepi2monitor.confに設定し、commandに"/opt/mechatrax/etc/ups_shutdown"を指定する

このキャパシタ基板を利用することで、リレー付き電源のように電圧の異なる電源を2つ用意する必要はなくなります。