Low Battery Alarm on macOS


macOS has no built-in low-battery alarm beyond the single 10% notification, and that notification can't be made louder or persistent.

So I frequently had the situation that I was busy working, got the notification, but ignored it.

And then soon later got “surprised” by an emergency shutdown at 0% left. 😖

Solution: Use launchd + speech (can't be missed)

Speech output works even with “Do Not Disturb” enabled and requires no permissions.

1. Create the script

~/bin/battery-alarm.sh

#!/bin/bash
pmset -g batt | grep -q "AC Power" && exit 0

pct=$(pmset -g batt | grep -Eo '[0-9]+%' | head -1 | tr -d '%')
[ "$pct" -gt 9 ] && exit 0

osascript -e 'set volume output volume 80 without output muted'

for i in 1 2 3; do afplay /System/Library/Sounds/Sosumi.aiff; done

say "Battery at $pct percent. Plug in the charger."

osascript -e "display alert \"Battery at $pct%\" message \"Plug in the charger.\" as critical"

Make it executable:

chmod +x ~/bin/battery-alarm.sh

2. Create the launch agent

~/Library/LaunchAgents/local.battery-alarm.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "<http://www.apple.com/DTDs/PropertyList-1.0.dtd>">
<plist version="1.0"><dict>
  <key>Label</key><string>local.battery-alarm</string>
  <key>ProgramArguments</key>
  <array><string>/Users/YOURNAME/bin/battery-alarm.sh</string></array>
  <key>StartInterval</key><integer>60</integer>
  <key>RunAtLoad</key><true/>
</dict></plist>

Replace YOURNAME with your short user name.

3. Load it

launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/local.battery-alarm.plist

To unload:

launchctl bootout gui/$(id -u)/local.battery-alarm