Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save pothi/49c8439354a6cffc06b5e2ebe9c2fce2 to your computer and use it in GitHub Desktop.

Select an option

Save pothi/49c8439354a6cffc06b5e2ebe9c2fce2 to your computer and use it in GitHub Desktop.
macOS Sleep Battery Draining Temporary Fix (Turn Wifi + Bluetooth off when sleeping)

macOS Sleep Battery Draining Temporary Fix

This guide provides a workaround for macOS battery drain issues during sleep by automatically disabling Bluetooth and WiFi when the system sleeps and re-enabling them on wake.

Problem

macOS currently has issues with battery draining during sleep when Bluetooth and WiFi remain active.

Solution Overview

Use sleepwatcher to run scripts that:

  • Disable Bluetooth and WiFi when the system goes to sleep
  • Re-enable Bluetooth and WiFi when the system wakes up

Prerequisites

Install Required Tools

  1. Install Homebrew (if not already installed):
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
  1. Install sleepwatcher:
brew install sleepwatcher
  1. Install blueutil (for Bluetooth control):
brew install blueutil

Setup Instructions

Step 1: Create Sleep Script

Create ~/.sleep file:

cat > ~/.sleep << 'EOF'
#!/bin/bash
exec >> ~/lid-events.log 2>&1

echo "Lid closed or system sleeping at $(date)"

# Print battery level
echo "Battery level $(pmset -g batt | grep -Eo '\d+%' | cut -d% -f1)%"

# Run commands in background with nohup to avoid blocking sleep
nohup sh -c '/opt/homebrew/bin/blueutil --power 0 2>/dev/null; networksetup -setairportpower en0 off 2>/dev/null' &>/dev/null &

# Exit immediately to let system sleep
exit 0
EOF

Step 2: Create Wake Script

Create ~/.wakeup file:

cat > ~/.wakeup << 'EOF'
#!/bin/bash
exec >> ~/lid-events.log 2>&1

echo "Lid opened or system woke up at $(date)"

# Print battery level
echo "Battery level $(pmset -g batt | grep -Eo '\d+%' | cut -d% -f1)%"

/opt/homebrew/bin/blueutil --power 1; networksetup -setairportpower en0 on
EOF

Step 3: Set Permissions

Make scripts executable:

chmod +x ~/.sleep ~/.wakeup

Step 4: Start Sleepwatcher Service

Start and enable the service to run at login:

brew services start sleepwatcher

Step 5: Verify Service is Running

Check that sleepwatcher is active:

brew services list | grep sleepwatcher

You should see:

sleepwatcher started         [username] ~/Library/LaunchAgents/homebrew.mxcl.sleepwatcher.plist

Important Notes

First-Time Execution Permissions

⚠️ On first execution, macOS will likely prompt for permissions:

  1. Terminal/iTerm Access: You may need to grant Terminal or your terminal app permission to control system settings

    • Go to System Settings → Privacy & Security → Accessibility
    • Add and enable your terminal application
  2. Network Configuration Access: The networksetup command may trigger a permission dialog

    • Click "Allow" when prompted
  3. Automation Permissions: You might need to approve automation access

    • Go to System Settings → Privacy & Security → Automation
    • Enable necessary permissions for Terminal

Monitoring

Check the log file to verify it's working:

tail -f ~/lid-events.log

You should see entries like:

Lid closed or system sleeping at [timestamp]
Lid opened or system woke up at [timestamp]

Verify Bluetooth and WiFi Status

After sleep/wake, verify the radios are being controlled:

# Check Bluetooth status
blueutil --power

# Check WiFi status
networksetup -getairportpower en0

Troubleshooting

If Scripts Don't Execute

  1. Check sleepwatcher is running:
brew services list | grep sleepwatcher
  1. Restart the service:
brew services restart sleepwatcher
  1. Check for errors in system log:
log show --predicate 'process == "sleepwatcher"' --last 1h

If System Wakes Immediately After Sleep

This setup uses nohup and background execution to prevent immediate wake. If you still experience issues:

  1. Verify the .sleep script has the correct content with background execution
  2. Ensure you're using the exact script format provided above
  3. Check that blueutil is installed at /opt/homebrew/bin/blueutil

To Disable This Fix

If you want to stop using this workaround:

brew services stop sleepwatcher

To completely uninstall:

brew services stop sleepwatcher
brew uninstall sleepwatcher
rm ~/.sleep ~/.wakeup

Why This Works

  • sleepwatcher: Monitors system sleep/wake events and triggers scripts
  • Background execution: Using nohup and & prevents the commands from blocking the sleep process
  • Immediate exit: The script exits quickly, allowing the system to complete the sleep transition
  • Logging: All events are logged to ~/lid-events.log for troubleshooting

Note

This is a temporary workaround until Apple fixes the underlying battery drain issue in macOS. The solution has been tested and confirmed to work without causing immediate wake issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment