r/macsysadmin • u/dech4 • 2h ago
Sending an iMac/Mini to uninteruppted deep sleep.
I've successfully got an intel iMac to sleep with no dark/maintenance/RTC etc wake events. Here is a guide; I'd be interested to get responses as to whether it's clear enough and works.
It's appreciated that a guide with no commentary is easiest to follow, but since it's environentally useful and apparently nothing else is available; this is provided. One script presumes that Karibineer elements is installed; if not then anything related to it can be deleted or if left it should do nothing -so not an issue. The outcome is that the device should be sleeping using about .3 watts vs about 1.3 with idle sleep and 10 or so with Display sleep.
The outcome after waking is that it takes about 12 secs. for the RAM contents to be written from the SSD and Bluetooth takes a couple of seconds after that to work and then there's another 15 secs or so before the WiFi wakes up but that latter is usually a non issue as reading or typing can be done in that period.
1. Prerequisites and Baseline Setup
Hammerspoon Installation & Permissions
Hammerspoon is a lightweight, open-source automation tool for macOS that interacts natively with system APIs without requiring System Integrity Protection (SIP) to be disabled.
- Download Hammerspoon from hammerspoon.org or its official GitHub repository and move it to your Applications folder.
- Open System Settings > General > Login Items and add Hammerspoon to Open at Login.
- Open System Settings > Privacy & Security > Accessibility and enable Hammerspoon.
- Open System Settings > Privacy & Security > Input Monitoring and enable Hammerspoon (allows global detection of the sleep shortcut).
Calendar Notification Toggles
Open the Calendar app, go to Settings / Preferences > Alerts, and set Default Alerts for events and all-day events to None. This prevents the OS from scheduling hardware RTC wake timers for upcoming calendar items.
Baseline Power Settings (pmset)
Setting a standard automated idle sleep timer in System Settings (or via pmset sleep) acts as a primary defense for short absences. This idle sleep timing prevents excessive SSD write wear from RAM during brief breaks, reserving aggressive hibernatemode 25 strictly for manual overnight hibernation.
Run this command in Terminal to disable standard network wake triggers:
Bash
sudo pmset -a tcpkeepalive 0 powernap 0 womp 0
2. macOS System Daemon Overrides
Analytics Deactivation (osanalyticsd)
The analytics daemon regularly sets RTC alarms to run local engagement checks. Unload the daemon to prevent it from queuing hardware wake requests:
Bash
sudo launchctl bootout system/com.apple.osanalyticsd
Internal Timer Suppression (powerd.plist)
Desktop Macs ignore standard sleep settings for CSPNEvaluation internal tasks. Placing a FeatureFlag override in the system domain forces powerd to abandon Smart Power Nap logic permanently without altering file permissions or risking macOS update failures.
Create the configuration file:
Bash
sudo nano /Library/Preferences/FeatureFlags/Domain/powerd.plist
Paste this XML structure:
XML
<?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">
<!-- Disables 2-hour CSPNEvaluation RTC dark wakes on macOS Sequoia and stops mDNSResponder maintenance wakes -->
<!-- Bluetooth radio toggles & pmset schedule cleanup in Hammerspoon config file remain required to block external wake triggers -->
<dict>
<key>CoreSmartPowerNap</key>
<dict>
<key>Enabled</key>
<false/>
</dict>
</dict>
</plist>
3. Passwordless Authorization & Hammerspoon Script
To allow Hammerspoon to manage system sleep modes and toggle system agents without requiring an admin password prompt on every execution, configure a sudoers rule:
- Run:
sudo nano /etc/sudoers.d/btt_bluetooth - Paste:
z ALL=(ALL) NOPASSWD: /usr/bin/pmset, /bin/launchctl - Save (
Ctrl + O,Enter) and exit (Ctrl + X).
Click the Hammerspoon menu bar icon, select Open Config, paste the following Lua script, save, and choose Reload Config:
Lua
-- ==========================================
-- 1. MANUAL TRIGGER (Option + /)
-- ==========================================
hs.hotkey.bind({"alt"}, "/", function()
-- 8-second pause to allow unplugging of USB peripherals
-- MUST remain >= 8 seconds to prevent physical key release from triggering a wake
hs.timer.doAfter(2, function()
local karabiner = hs.application.get("Karabiner-Elements")
if karabiner then karabiner:kill() end
hs.execute("sudo /bin/launchctl bootout gui/$(id -u) /System/Library/LaunchAgents/com.apple.bluetoothuseragent.plist")
hs.execute("sudo /usr/bin/pmset schedule cancelall")
-- Lock into h25 and sleep
hs.execute("sudo /usr/bin/pmset -a hibernatemode 25")
hs.execute("sudo /usr/bin/pmset sleepnow")
end)
end)
-- ==========================================
-- 2. AUTOMATED WAKE MANAGEMENT
-- ==========================================
wakeWatcher = hs.caffeinate.watcher.new(function(eventType)
if eventType == hs.caffeinate.watcher.systemDidWake then
-- Wait 2 seconds for powerd to log the wake event
hs.timer.doAfter(2, function()
hs.execute("pmset -g log | grep -i 'Wake from' | tail -n 1", function(exitCode, stdOut)
local logLine = (stdOut or ""):lower()
-- ONLY intervene if it is a manual Power Button wake
if logLine:find("powerbutton") then
hs.execute("sudo /usr/bin/pmset -a hibernatemode 0")
hs.execute("sudo /bin/launchctl bootstrap gui/$(id -u) /System/Library/LaunchAgents/com.apple.bluetoothuseragent.plist")
hs.application.launchOrFocus("Karabiner-Elements")
end
-- If it is an RTC/Maintenance wake, do nothing. macOS will return to h25 natively.
end)
end)
end
end)
wakeWatcher:start()
```[cite: 2]
---
## 4. Daily Operational Workflow
* **Initiating Deep Sleep:** Press `Option` + `/`[cite: 2]. You have **8 seconds** to unplug any wired USB mouse and release all physical keys[cite: 2].
* **Waking the Computer:** Press the physical **Power Button**[cite: 2]. Wait roughly **15 seconds** after the screen lights up to allow Bluetooth, Karabiner-Elements, and Wi-Fi to initialize cleanly before clicking[cite: 2].
* **Automatic `hibernatemode 0` Reversion:** Upon waking, Hammerspoon automatically resets `hibernatemode` back to `0`[cite: 2]. This ensures short idle breaks during the day use low-impact RAM sleep rather than wearing down your SSD with full 8GB+ RAM dump writes, reserving `hibernatemode 25` strictly for intentional overnight hibernation[cite: 2].
