How your Mac may talk in its sleep thanks to HID

Of all the features of Macs, none can have been more troublesome over the years than sleep and wake. If you’re lucky enough to have – for the moment at least – a model whose firmware currently doesn’t cause a kernel panic with either of these events, then you may instead be troubled by your Mac waking up when it shouldn’t.

In search of the simpler life, I confess that I’ve largely given up trying to use sleep on my two main Macs. I shut down my MacBook Pro between uses rather than leaving it asleep overnight; as it’s only heavily used for three months of the year between June’s first beta of the next major version of macOS and its release in the autumn/fall, that’s tolerable. My desktop iMac Pro stays on 24/7, being restarted as infrequently as possible; as it’s in use for up to 19 hours a day, messing around with sleep for the remaining few doesn’t seem worth the effort.

Besides, I’ve noticed one slightly strange thing about my iMac Pro and its sleep potential: according to Activity Monitor, there’s always one process which stops it from sleeping: hidd. This article is the story of my trip through absent documents to discover what and why that is.

nosleep01

If your Mac is having problems getting to sleep, or waking when it shouldn’t, the Energy tab in Activity Monitor is a good starting point, as it shows which processes are currently blocking sleep. In the case of my iMac Pro, the only one which just sits there is hidd, a name which meant next to nothing to me. After checking its man page, I was none the wiser, as Apple could have saved its words by just writing “poke off”. Its description reads: “hidd – The HID library userland daemon”, which is confounded by this explanation: “As the HID libraries expand, hidd is the place where things better done in userland reside. It is not invoked, nor does it have any options.” And that’s for version 2.0.0 dated 08-04-2020.

I went back to Activity Monitor, where there was little to find about hidd. It didn’t seem to work with files on disk much, nor access the network.

nosleep02

I then stumbled across an old and now-retired reference manual among Apple’s developer documentation, Accessing Hardware From Applications, in which there is a key piece of information let slip in passing:
“HID family. Through the HID Manager, the HID family provides a device interface for accessing a variety of devices, including joysticks and other game devices, audio devices, non-Apple displays, and UPS (uninterruptible power supply) devices. Note that you can use the Carbon Event Manager and NSEvent interfaces described in Hardware-Access Options to monitor mouse and keyboard actions.”

You’ll no doubt be relieved to know that I don’t have a secret stash of game controllers, but I do have a UPS. Since upgrading to Catalina, I’ve been puzzled by the entries in its log which this makes on average about once every second. A detailed listing of those log entries is in the appendix below in case you’re interested, but they show that every second or so my Mac is polling the status of its UPS, checking whether mains power is still available, and so on. This is marked by the log message
SystemUIServer Battery powerManagementUpdated

nosleep03

This repeated sequence involves ioupsd, a daemon to track the UPS state, and powerd, a daemon to manage Energy Preferences. That looked like evidence that hidd was being kept running to handle this polling. My next step was to see what happened to this during sleep: if it stopped, then my Mac wouldn’t know when there was a mains power outage, and would be unable to respond as set in the Energy Saver pane. If it continued, then it would be a significant limitation on sleep. So I forced a sleep and after five minutes studied the log. As you’ll probably have guessed, the UPS polling continued through sleep, even though everything else went silent.

If you power your Mac from a UPS (as everyone should), then you might like to reconsider the value of letting it sleep. When it does, it will continue to check that its mains power supply is good, which rather defeats the purpose of sleep. None of this applies to laptops, of course, which don’t communicate with a UPS, as they have their own internal power supply and don’t need to shut down a UPS in the event of a mains supply outage.

Appendix: UPS Check Log Sequence

The following log entries are characteristic of a desktop Mac running 10.15.5, connected to a supported UPS using USB ports. These sequences are repeated approximately once every second, and continue even when the Mac is supposed to be asleep.

They start with a series of messages similar to
2.475159 com.apple.iohid ups ioupsd IOHIDLib Skipping duplicate element (UP : 85 U : 44 Type : 2 IV: 0) with key Is Charging

following which are
2.475236 com.apple.iohid ups ioupsd IOHIDLib Power Source status isACSource : Yes , isCharging : No , isDischarging : No
2.475281 com.apple.iohid ups ioupsd IOHIDLib dispatchEvent: {
"Current Capacity" = 100;
"Delayed Remove Power" = "-1";
"Enable Audible Alarm" = 2;
"Is Charging" = 0;
"Max Capacity" = 100;
"Power Source State" = "AC Power";
"Set Required Voltage" = 230;
"Time to Empty" = 43;
Voltage = 27090;
}
2.475396 powerd Received power source(psid:5000) update from pid 407: <private>
2.475433 powerd Battery time remaining posted(0x1000000008d002b) Time:43 Source:AC
2.475443 powerd posted 'com.apple.system.powersources'
2.475581 SystemUIServer Battery powerManagementUpdated
2.475737 com.apple.utilities powermanagement AMPLibraryAgent AMPLibraryAgent pm) power source is battery = N
2.476014 SystemUIServer Battery BME updateMenu: <CFArray 0x600000544b80 [0x7fff8ed05b60]>{type = immutable, count = 1, values = (
0 : {
"Current Capacity" = 100;
"Delayed Remove Power" = "-1";
"Enable Audible Alarm" = 2;
"Is Charging" = 0;
"Is Present" = 1;
"Max Capacity" = 100;
Name = "Back-UPS XS 1400U FW:926.T2 .I USB FW:T2 ";
"Power Source ID" = 26673152;
"Power Source State" = "AC Power";
"Product ID" = 2;
"Set Required Voltage" = 230;
"Time to Empty" = 43;
"Transport Type" = USB;
Type = UPS;
"Vendor ID" = 1309;
Voltage = 27090;
}
)}