最初にまとめ
- 無線がないと操作しづらいRaspberryPi Zeroの無線接続状態の自動監視&復旧をしてみたよ
- 実際に一週間くらい運用して、劇的に改善したよ
きっかけ
机で遊んでたRaspberry Pi Zero にSNS向け自作botを入れて24時間運用させているんですが、何かのタイミングでこのラズパイがハングアップして再起動を余儀なくされて早一ヶ月。さすがにイラッとしてちゃんと原因を調べてみたら無線接続でトラブってそのままハングアップしてしまっていたようです。
なのでラズパイが無線接続できているかどうかを自動監視させて、もし切断されていたら再接続、それでもだめならラズパイ本体を再起動という方法で、人間の手による世話を解放させてみました。
実施環境 (2025/09/04時点)
- Raspberry Pi Zero WH
- Raspbian GNU/Linux 12 (bookworm)
- 32GB SDカード
- 2.4GHz WiFi(自宅の無線ルーター)
WiFi接続を監視するスクリプト
(環境に合わせて書き換えてください
#!/usr/bin/env bash
set -Eeuo pipefail
# ========= 設定 =========
GATEWAY_IP="192.168.1.1" # ご自身のゲートウェイに置き換えてください
FALLBACK_IP="1.1.1.1" # 外部到達性チェック用
PING_COUNT=2
RETRY=3 # 連続失敗回数の閾値
LOGTAG="wifi-watchdog"
STATEFILE="/run/wifi-watchdog.fail"
# ========= 関数 =========
log(){ logger -t "$LOGTAG" -- "$*"; }
ping_ok(){ ping -c "$PING_COUNT" -W 2 "$1" > /dev/null 2>&1; }
# ========= 本体 =========
fail=0
if [ -f "$STATEFILE" ]; then
fail=$(cat "$STATEFILE" || echo 0)
fi
if ping_ok "$GATEWAY_IP" || ping_ok "$FALLBACK_IP"; then
# 成功: カウンタリセット
echo 0 > "$STATEFILE"
exit 0
fi
# 失敗: カウントアップ
fail=$((fail+1))
echo "$fail" > "$STATEFILE"
log "Connectivity check failed ($fail/$RETRY)."
if [ "$fail" -lt "$RETRY" ]; then
# まずWi‑Fiリセットで様子見
log "Restarting Wi‑Fi via NetworkManager..."
nmcli radio wifi off || true
sleep 5
nmcli radio wifi on || true
exit 0
fi
log "Connectivity failed $RETRY times. Rebooting the system..."
/sbin/reboot -f
監視スクリプトファイルへ権限付与
sudo chown root:root /usr/local/sbin/wifi-watchdog.sh
sudo chmod 755 /usr/local/sbin/wifi-watchdog.sh
systemdサービスの追加
このサービス自体は直接起動させず、次に用意するタイマーから起動させるようにします。
特に凝ったことはしていなくて、ネットワークがオンラインになった後から起動させますよという優先順位をそれとなく指定しているくらいです。
[Unit]
Description=Network connectivity watchdog (Wi-Fi auto-recover/reboot)
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/wifi-watchdog.sh
[Install]
WantedBy=multi-user.target
タイマーの追加
監視は5分おきにするようにしていますが10秒のずれを許容しています (厳密な監視が不要だったので)
[Unit]
Description=Run wifi-watchdog every five minutes
[Timer]
OnBootSec=2min
OnUnitActiveSec=5min
AccuracySec=10s
RandomizedDelaySec=15s
Persistent=true
[Install]
WantedBy=timers.target
タイマーの有効化
sudo systemctl daemon-reload
sudo systemctl enable --now wifi-watchdog.timer
#タイマーが有効化されていることを確認
systemctl list-timers | grep wifi-watchdog
さいごに
以上の内容を実際に一週間くらい運用してみました。それまで毎日数回の再起動が必要なくらいの頻度で無線接続がトラブっていましたが、それが一週間に数回程度の再起動に減りました。
「なんだよ、完全解決したのじゃないのかよ」というお叱りはごもっともで御座います。たぶん無線じゃなくて別のところでハングアップしてると思われるので、こちらについてはまた別の対策を追加してみたいと思ってます(礼)