Your Pi 5 shut down and you don't know why? This tool makes sure that never happens again.
pi-power-guard is a lightweight daemon that monitors all power rails on your Raspberry Pi 5's PMIC (Power Management IC) every second. It does three things:
- Warns before crashes -- detects voltage drops and trends before the hardware under-voltage alarm triggers
- Preserves evidence -- crash-resilient logging ensures you have data from the seconds before a power failure (journald loses up to 5 minutes)
- Post-crash forensics -- on every boot, automatically determines why your Pi shut down (power cycle, watchdog reset, or software reboot)
Zero dependencies. Single Python file. Just install and forget.
Raspberry Pi 5 can shut down suddenly due to PSU issues, USB-C cable problems, or power fluctuations. When this happens:
- journald loses up to 5 minutes of logs (default
SyncIntervalSecis 5 minutes) - No under-voltage warning appears if power drops too fast for the firmware to react
- pstore/ramoops don't survive power loss on Pi (DRAM-based, not persistent)
- You're left with zero evidence of what happened
This tool was born after investigating a real Pi 5 that shut down mysteriously -- no kernel panic, no OOM, no under-voltage in logs, nothing. Other devices on the same network were fine. The existing monitoring (5-minute cron job) left a 5-minute data gap right when it mattered most.
- 26 PMIC Rail Monitoring -- reads every power rail voltage and current via
vcgencmd pmic_read_adc - Total Power Consumption -- real-time wattage calculated from all V*A rail pairs
- Voltage Trend Detection -- EMA-based slope analysis warns before hardware under-voltage triggers
- Crash-Resilient Logging --
fdatasyncevery 10 seconds with ring buffer rotation (max ~10s data loss vs 5 minutes with journald) - Boot Crash Detection -- analyzes PM_RSTS register, state files, and ext4 recovery to determine what happened
- Previous Session Summary -- on boot, reports ext5v min/max/avg, warn/alert counts, and power consumption from the previous session
- Throttle State Decoding -- human-readable
get_throttledbitmask with change tracking - CPU/GPU Frequency Tracking -- detects frequency changes to correlate with throttle events
- Temperature + Fan Monitoring -- CPU, PMIC, NVMe temps and fan RPM with configurable thresholds
- Prometheus Export -- optional textfile collector
.promoutput for Grafana integration - systemd Integration --
Type=notifywith sd_notify watchdog, security hardening - Zero Dependencies -- Python 3.11+ stdlib only, single file (~1100 lines)
- One-Shot Diagnostic --
--checkflag for instant health report
- Raspberry Pi 5 (any RAM variant)
- Raspberry Pi OS Bookworm (Debian 12, aarch64)
- Python 3.11+
One-command install:
git clone https://github.com/mahsumaktas/pi-power-guard.git
cd pi-power-guard
sudo bash install.shThe installer will:
- Verify Pi 5 hardware and Python version
- Install the daemon and config
- Optionally enable hardware watchdog, tune journald, and configure systemd watchdog
- Start the service
Verify it's running:
systemctl status pi-power-guard
tail -f /var/log/pi-power-guard/current.logRun a single health check without starting the daemon:
sudo python3 /opt/pi-power-guard/pi_power_guard.py --checkExample output (real Pi 5 data):
pi-power-guard v1.1.0 -- One-Shot Check
================================================
Boot Analysis:
PM_RSTS: 0x1000 (POWER_CYCLE)
Previous Shutdown: BOOTED
Previous Time: 2026-03-27T16:25:33+0300
ext4 Recovery: Yes
Power Rails (PMIC):
0v8_aon_a 0.003 A
0v8_aon_v 0.801 V
0v8_sw_a 0.368 A
0v8_sw_v 0.803 V
1v1_sys_a 0.177 A
1v1_sys_v 1.104 V
1v8_sys_a 0.198 A
1v8_sys_v 1.797 V
3v3_sys_a 0.121 A
3v3_sys_v 3.307 V
3v7_wl_sw_a 0.082 A
3v7_wl_sw_v 3.704 V
ext5v_v 5.140 V [OK]
hdmi_a 0.015 A
hdmi_v 5.146 V
vdd_core_a 1.161 A
vdd_core_v 0.836 V
...
Throttle State:
Raw: 0x0
Flags: None
Temperatures:
CPU 47.4 C [OK]
PMIC 47.8 C [OK]
NVMe 30.9 C [OK]
Total Power: 2.60 W
Fan Speed: 2730 RPM
Frequencies:
CPU 1500 MHz
GPU 500 MHz
Voltage Alarm: No
Edit /etc/pi-power-guard/config.ini. Changes take effect after sudo systemctl restart pi-power-guard.
| Section | Key | Default | Description |
|---|---|---|---|
| general | poll_interval |
1 |
Seconds between sensor reads |
| general | baseline_interval |
5 |
Seconds between full log entries (even without changes) |
| general | sync_interval |
10 |
Seconds between fdatasync (10 for NVMe, 30 for SD card) |
| general | ring_buffer_lines |
100000 |
Max lines before log rotation |
| thresholds | ext5v_warn |
4.85 |
EXT5V warning threshold (V) |
| thresholds | ext5v_low |
4.75 |
EXT5V low threshold (V) |
| thresholds | ext5v_critical |
4.50 |
EXT5V critical threshold (V) |
| thresholds | cpu_temp_warn |
75.0 |
CPU temperature warning (C) |
| thresholds | cpu_temp_critical |
85.0 |
CPU temperature critical (C) |
| trend | window_size |
60 |
Samples in trend analysis window |
| trend | drop_threshold |
0.15 |
Voltage drop (V) that triggers warning |
| prometheus | textfile_dir |
(empty) | Path for .prom file output (e.g. /var/lib/node_exporter/textfile_collector) |
See config.ini for all options with descriptions.
Each line follows: TIMESTAMP LEVEL SUBSYSTEM key=value ...
Real output from a Pi 5 after a power cycle:
2026-03-27T16:25:32+0300 BOOT SYSTEM version=1.1.0 hostname=raspberrypi python=3.11.2
2026-03-27T16:25:33+0300 BOOT CRASH pm_rsts=0x1000 type=POWER_CYCLE prev_state=clean ext4_recovery=true
2026-03-27T16:25:33+0300 BOOT PREV_SESSION ext5v_min=5.101 ext5v_max=5.166 ext5v_avg=5.138 samples=5431 warns=0 alerts=0
2026-03-27T16:25:35+0300 INFO PMIC ext5v_v=5.135 ... 3v3_sys_v=3.310 total_w=2.18
2026-03-27T16:25:35+0300 INFO THROTTLE raw=0x0 flags=none
2026-03-27T16:25:35+0300 INFO TEMP cpu=46.3 pmic=47.8 nvme=30.9 fan=2736rpm
2026-03-27T16:25:35+0300 INFO FREQ cpu=1600MHz gpu=500MHz
What a voltage drop event looks like:
2026-03-27T14:35:16+0300 WARN TREND rail=ext5v_v ema=4.890 slope=-0.0820 msg="voltage trending down"
2026-03-27T14:35:17+0300 WARN PMIC ext5v_v=4.842 threshold=4.85 msg="EXT5V below warning threshold"
2026-03-27T14:35:22+0300 ALERT PMIC ext5v_v=4.720 threshold=4.75 msg="EXT5V below low threshold"
2026-03-27T14:35:22+0300 WARN THROTTLE raw=0x50005 flags=throttled,under-voltage changed="throttle:+throttled,under-voltage"
| Level | Meaning |
|---|---|
BOOT |
Startup info and crash detection (once per boot) |
INFO |
Normal baseline snapshot |
WARN |
Voltage trending down, temperature rising, throttle flags active |
ALERT |
Voltage below threshold, temperature critical |
Useful grep commands:
# All alerts
grep ALERT /var/log/pi-power-guard/current.log
# Crash reports
grep "BOOT CRASH" /var/log/pi-power-guard/current.log
# EXT5V voltage history
grep "ext5v_v=" /var/log/pi-power-guard/current.log
# Throttle events only
grep "THROTTLE" /var/log/pi-power-guard/current.log | grep -v "flags=none"
# Power consumption history
grep "total_w=" /var/log/pi-power-guard/current.log
# CPU frequency changes (throttle indicator)
grep "FREQ" /var/log/pi-power-guard/current.log
# Previous session summaries
grep "PREV_SESSION" /var/log/pi-power-guard/current.logEvery second, pi-power-guard reads all sensors (PMIC rails, temperatures, fan speed, CPU/GPU frequency, throttle state). It compares with the previous reading and logs when:
- Any voltage changes by more than 10mV
- Any temperature changes by more than 1C
- Throttle state or CPU frequency changes
- Or every 5 seconds as a baseline (configurable)
Each log cycle also calculates total power consumption (sum of V*A for all rail pairs).
On every boot, pi-power-guard checks:
-
PM_RSTS register (
vcgencmd get_rsts) -- the hardware reset reason:0x1000= Power cycle (PSU failure, cable disconnect)0x1020= Software reboot (clean reboot or kernel panic)0x1040= Watchdog reset (system hang detected)
-
State file (
/var/lib/pi-power-guard/last-state) -- written on clean shutdown with timestamp. If the file says "booted" instead of "clean", the previous shutdown was unclean. -
ext4 recovery -- checks
journalctlfor "EXT4-fs recovery" messages, confirming filesystem was dirty. -
Previous session summary -- analyzes the previous log file and reports EXT5V min/max/average, total samples, warning/alert counts, and average power consumption. This gives you a complete picture of the previous session's health at a glance.
Each monitored rail (EXT5V, 3V3_SYS, VDD_CORE, 1V8_SYS) has its own tracker using:
- Exponential Moving Average (EMA) with alpha=0.1 for noise-resistant current estimate
- Half-window slope: compares average of last 30 samples vs previous 30 samples
- Warns when slope exceeds -0.15V (voltage dropping 150mV over 30 seconds)
This catches gradual PSU degradation that absolute thresholds would miss until the last moment.
- Logs written to ring buffer file with
fdatasyncevery 10 seconds - On sudden power loss, at most ~10 seconds of data is lost (vs 5 minutes with default journald)
- Automatic rotation when file exceeds 100k lines, keeping up to 5 archives
- Total disk usage: ~50MB maximum
# Service status
systemctl status pi-power-guard
# View live logs
tail -f /var/log/pi-power-guard/current.log
# Reload config without restart (SIGHUP)
sudo systemctl reload pi-power-guard
# Restart after config changes
sudo systemctl restart pi-power-guardThe service runs with security hardening (ProtectSystem=strict, ProtectHome=true, NoNewPrivileges=true) and resource limits (CPUQuota=5%, MemoryMax=50M).
cd pi-power-guard
sudo bash uninstall.shMeasured on a real Pi 5 (8GB, NVMe):
| Metric | Value |
|---|---|
| CPU | ~0.3% average |
| RAM | ~15 MB RSS |
| Disk | ~50 MB max (ring buffer + archives) |
| I/O | 1 fdatasync per 10 seconds |
Does it work on Raspberry Pi 4?
No. vcgencmd pmic_read_adc is Pi 5 specific (Renesas DA9091 PMIC). Pi 4 doesn't have this command.
Is it safe on SD card?
Yes. Set sync_interval = 30 in config.ini to reduce writes. At 100 bytes per log line, even per-second logging produces only ~8MB/day.
How much CPU does it use?
~0.5% average (25ms work per 1-second cycle). Three vcgencmd subprocess calls and a few sysfs reads.
What's the difference between this and vcgencmd get_throttled?
get_throttled tells you the current state. pi-power-guard gives you the history -- what happened in the seconds before a crash, voltage trends over time, and forensic boot analysis.
Can I use it alongside RPi-Monitor or Prometheus?
Yes. pi-power-guard writes to its own log files and doesn't interfere with other monitoring. For Prometheus integration, set textfile_dir in config.ini to your node_exporter's textfile collector directory and all metrics will be exported automatically.
How is total power calculated?
For each PMIC rail pair (e.g. EXT5V_V and EXT5V_A), it multiplies voltage by current and sums all pairs. This gives the total power drawn through the PMIC, which covers most of the Pi's consumption (CPU, GPU, memory, I/O). Note: USB peripherals powered externally are not included.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing) - Commit your changes
- Push to the branch
- Open a Pull Request
MIT License. See LICENSE for details.