UPSを自作する【Anker】


前回の投稿から2年近く時が経ってしまいました。
私のモチベーション維持のために、読んだらいいねをお願いします!

何をやったか・工夫した点

  • この記事を見れば汎用ポータブル電源からUPSを作れます。
  • Ankerのポータブル電源をUPSとして使い、停電時に自動シャットダウン機能を追加してUPSを自作した。
  • 専用のUPSを使わなくても安価で高性能なUPSを自作することができた。
  • 停電監視用でUSB電源を取り出し、減圧した上でRaspberryPiに監視させた

はじめに

3年前にSIer営業1年目がDockerを使ってファイルサーバを構築してみたという記事を投稿し、自宅にファイルサーバがあるという満足感に浸ることができました。
しかし、

  • それなりに電気代を食うので、使うときにつけて夜にシャットダウンする、みたいな運用をしているため使いたいときにすぐ使えない
  • 無駄に拡張性を考慮してでかいケースを買ってしまったので、邪魔。

ということがあり、ちょっとずつストレスが溜まってきたので、いっそのこと製品にしてしまおう、ということで、ファイルサーバをQNAPに移行しました!
結果的に大正解で、電気代も80W→30W程度まで減らすことができ、常時起動でストレスフリー&スペースを大幅に削減することができました。
ここで気になるのは停電。めんどくさがりや&ズボラというエンジニア適正100%な私は便利な家電が大好きなのです。
そのため、極稀にブレーカーを落とすことがあり、停電でNASやHDDが壊れてデータがなくなると困る!ということでUPSを導入しようと思いました。
・・・が、個人で買うにちょっと躊躇する値段(安くても1万弱、高いと数万)、、、
ということで探していると、Ankerから素晴らしい製品が出ていました。

ポイントはここ!

なんと、パススルーに対応し、125WまでであればUPSとして使えます。
なので、普段はUPSとして使い、キャンプ等に行くときはポータプル電源として使える2way方式が可能!
(キャンプ行ったことないけど)
一般的なUPSであれば、停電を検知した場合には製品にシャットダウンコマンドを送り、自動的にシャットダウンされるような仕組みがありますが、この製品にはそのような機能はありません。
自宅にいるときに停電が起きればよいのですが、外出中に停電した場合は充電がどんどんなくなり、力尽きるという時間差停電が起こるだけです。

なので、停電した場合にQNAPにシャットダウンコマンドを送り、安全にQNAPを停止する仕組みを作ります。

準備するもの

本システムの構築にあたり、以下の製品を使用しています。
また、RaspberryPiとQNAPは同一ネットワーク上に存在することを前提としています。

使用した製品 用途
Raspberry Pi 3 シャットダウンコマンドの発出用
QNAP TS-251D いわずもがな

本システムは電子回路の製作があるので、以下の製品を使っています。

部品名 型番 用途
三端子レギュレータ一式 TA48033S 5V→3.3Vの減圧
USB電源アダプタ 100均で適当なやつ 停電検知用
USBケーブル 家に転がってたやつ 停電検知用
ブレッドボード 家に転がってたやつ 配線用
ジャンパ線 家に転がってたやつ 配線用

仕組み

今回やりたいことは以下のとおりです。
USB電源から停電状況を監視し、停電を検出したらネットワーク越しにshutdownコマンドを発出し、QNAPをシャットダウンさせます。
QNAPをシャットダウンしている間はAnkerポータブル電源が電源を供給し続けるので、安全にシャットダウンすることができます。

①停電の検出

今回使用したAnkerの製品は最大入力が125W(電源+USBC)のため、それ以内に収めないと入力電力<出力電力となり、UPSの役割を果たせないので、UPS配下につなぐ製品の合計ワット数は125W以内に収めてください。
また、今回はsshによりシャットダウンを行うため、ネットワークが切断されるとシャットダウンコマンドを発出できません。
なので、ルーターやスイッチ等のNW機器類も保護するようにしてください。

USBケーブルは以下の様に4本の線が入っていて、

  • 1と4が電源ケーブル
  • 2と3が通信用ケーブル(今回不使用)

今回は電源を監視するので、1と4の電源ケーブルを使います。
今回使ったUSBアダプタは5Vなので、1-4間の電圧5Vとなります。そのままではラズパイに繋げないので、三端子レギュレータで減圧しています。

停電を検知するために、ラズパイへコンセントの電源を直接入力します。
ただし、ラズパイのGPIOの入力は3.3Vなので、USB電源アダプタを使用して100V→5V、三端子レギュレータを使って5V→3.3Vに減圧しています。
今回はGPIO23番を使用しています。

最終的に以下のような配線となりました。

停電を検知するプログラムは以下の通りです。
今回はGPIO23番を使用していますが、適宜読み替えてください。
また、必要なモジュールはインストールしてください。
1秒毎に電源の状態を監視し、60秒間GPIO23がOFF(=1分間停電状態が続いた)場合にはシャットダウンを発出するシェルスクリプト(qnap-shutdown.sh)が動く仕組みになっています。

power-outage.py
#必要なモジュールをインポート
import RPi.GPIO as GPIO             #GPIO用のモジュールをインポート
import time                         #時間制御用のモジュールをインポート
import sys                          #sysモジュールをインポート
import subprocess                   #シェルスクリプト呼び出し用

#ポート番号の定義
Sw_pin = 23                         #変数"Sw_pin"に23を格納

#GPIOの設定
GPIO.setmode(GPIO.BCM)              #GPIOのモードを"GPIO.BCM"に設定
#GPIO23を入力モードに設定してプルダウン抵抗を有効にする
GPIO.setup(Sw_pin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

SHELL_PATH = "${HOME}/qnap-shutdown/qnap-shutdown.sh"
TIME_OF_POWER_OUTAGE = 60


powerOutageTime = 0

#while文で無限ループ
#GPIO23の入力を読み取る
while True:
    if powerOutageTime >= TIME_OF_POWER_OUTAGE:            #1分超えた場合はシャットダウンコマンドの実行
        subprocess.call( ["bash",SHELL_PATH] )
        powerOutageTime = 0

    if GPIO.input(Sw_pin) == 1:         #GPIO23が「ONで"1"」「OFFで"0"」
        powerOutageTime = 0
    else:
        powerOutageTime += 1

   time.sleep(1)                       #1秒間待つ

②シャットダウンコマンドを発出する

上記で1分間入力がなかった場合停電したと見なし、以下のシャットダウンシェルを動かします。
ここは各環境によると思うので、適宜読み替えてください。
私はQNAPに公開鍵でsshできる設定にしています。
(公開鍵だけで入る方法はQNAPを再起動すると初期化される→今後の課題)

qnap-shutdown.sh
#!/bin/bash

password="PASSWORD"      #ここは各環境に合わせてください。
username="USERNAME" #ここは各環境に合わせてください。
host="HOST"  #ここは各環境に合わせてください。
port="PORT"  #ここは各環境に合わせてください。

expect -c "
        spawn ssh ${username}@${host} -p ${port} -i ${HOME}/.ssh/id_rsa
        expect \"ゆーざねーむ@ほすとめい's password:\"      #ここは各環境に合わせてください。
        send \"${password}\n\"
        expect \"~]\"
        send \"sudo poweroff\n\"  #シャットダウンコマンドの発出
        expect \"Password:\"
        send \"${password}\n\"
        expect \"~]\"
        send \"exit\n\"
        expect \"~]\"

終わりに

データがなくなるのは一瞬です。
QNAPでRAID構築&バックアップをしていても、停電で同時に消えてしまう可能性もあります。
仮に消えなかったとしても、製品やHDDに大きな負荷がかかることは間違いありません。
よって、可能な限り安全に運用できる環境を整え、安心して運用していきましょう。

今後の課題

  • シェルスクリプト内にパスワードが平文で入っている→公開鍵だけで入れるようにしたい
  • QNAP等の製品を安全にシャットダウンする仕組みとしてNUTという規格があるらしい

参考文献

【ラズパイ電子工作】スイッチのON/OFF状態を読み取る方法
Raspberry Piでスイッチ入力
低損失三端子レギュレーター
Raspberry Pi と BY50S と Ready NAS の連携
Raspberry Pi にNUTをセットアップする
NUT(Network UPS Tools)のmaster・slaveモードでの設定
QNAP TS-251+ の設定(UPSおよび他NASとの連携)