Letting the server machine sleep (macOS)

Another helpful page: http://www.cnpbagwell.com/mac-os-x/bonjour-sleep-proxy

Before the client goes to sleep, it must register with the server. It does this by sending a unicast Dynamic DNS Update which contains at a minimum a list of the TCP services (using SRV and TXT records) that should cause the computer to wake up, a Dynamic DNS Update Lease OPT record and a EDNS0 Owner OPT record directly to the server name and port from previous query.

and then

If someone attempts to establish a TCP connect to one of the services, the packet will be sent to server because of the ARP response. The server will detect this and send out a magic packet to wake the client but doesn’t respond to the TCP connection request. Once client awakes, it sends its own gratuitous ARP which reroutes the initial TCP connection packets to client and it responds to complete connection.

I guess macOS is doing all this, but it only registers the services it knows about with the sleep proxy. Since we’re running our own mdns server advertising services, they don’t get registered with the sleep proxy, and hence port 8089 access does not trigger a wake-up.

OK - i guess that could explain it.

one other thing is that i don’t see any sleep-preventing assertions on the server machine when the tvOS client is connected to the backend.

i guess there’s a chance that my downrev OS X is to blame here. one of my many todo list items is to install 10.12 on this machine onto a fresh SSD. the mac mini is pretty good at killing hard disks, and the (remaining) internal disk has a bunch of uncorrectable bad sectors…

rob

That’s a good catch.

I’m in the middle of a bunch of stuff at the moment, but I can circle back to the sleep proxy and switch us over to the system bonjour on macOS to get it working.

OK sounds good, i’ll disable sleep again for now… thx for working the problem.

Here’s an experimental build which switches to using the macOS native bonjour for advertisements:

curl -XPUT http://127.0.0.1:8089/updater/check/2017.04.27.1847

One difference now is that we no longer advertise a dvr-hostname.local, so you must use hostname.local. That’s probably going to break some people’s bookmarks if we end up pushing this out to everyone.

ok i am installing it now and will give it a try modulo any recordings that may be happening currently.

rob

I just fixed this as well. Another new build:

curl -XPUT http://127.0.0.1:8089/updater/check/2017.04.27.2118

OK let me pull that one, i have been preoccupied with other stuff today and was not able to test after i installed that build.

1 Like

OK there is a lot to report:

1 - if the server is sleeping, hitting the web server from another machine causes the server to wake up and eventually the DVR page is served. it takes a while for this machine to come up, so sometimes safari times out and i have to hit reload to see the server page. regardless the sleep proxy stuff is working now!

2 - OS X seems very aggressive about going back to sleep if there is no activity… like after 30s or so the machine falls asleep again.

3 - the tvOS app is able to wake the server just as hitting the webpage does. so that also is working. unfortunately though the tvOS app must give up looking for the server before it is ready, and so the DVR related menus never appear.

4 - if the server is awake and you exit and re-enter the tvOS app, it usually finds the server.

5 - the tvOS app being in contact with the server does not cause an assertion to appear. so if you linger too long in the interface, the server falls asleep again. once you start viewing a recording, the “recording engine is busy” assertion appears and the machine stays awake.

6 - watching a recording in the web interface does not cause an assertion to appear, so the server eventually falls asleep and the recording stops playing. then the server wakes up and the playback resumes, and the process repeats.

i think that’s all i’ve got for now, sorry i got tied up today with a bunch of auto insurance stuff.

edit: one more: if you are on a recording “watch” page in the tvOS app and the server is asleep, pressing “watch” causes the server to wake up. but then the tvOS app times out before the server is ready and returns to the ‘watch’ page. i looped on that about 3 times before the server found the recording and it started playing. so maybe longer timeouts are needed.

rob

Awesome!

How long does it take for the DVR to be fully up? Trying to get a sense for what the timeouts would need to be for this to work.

It does sound like it takes much longer than you’d hope, enough to make it annoying when you want to use the DVR to watch something.

Really? That seems strange. What is your sleep timeout set to in Energy prefs?

I fixed this for that last build, and am not able to reproduce here. I see an assertion as long as the tvOS app is open. Perhaps its related to the app not fully connecting to the backend correctly when it comes out of sleep.

Good catch, fixed for next build.

seems to take about 6-7 seconds. however i do have my recordings on an external USB3 disk which probably has something to do with the lag. i guess i should point the DVR backend at the internal disk just to get a lower bound.

htpc2:~ htpc$ pmset -g live
Active Profiles:
AC Power		-1*
Currently in use:
 standby              0
 Sleep On Power Button 1
 womp                 1
 autorestart          1
 hibernatefile        /var/vm/sleepimage
 darkwakes            0
 networkoversleep     0
 disksleep            0
 sleep                15 (sleep prevented by EyeTV, coreaudiod)
 autopoweroffdelay    14400
 hibernatemode        3
 autopoweroff         1
 ttyskeepawake        1
 displaysleep         10 (display sleep prevented by EyeTV, coreaudiod)
 standbydelay         4200

it seems like if it gets woken up by network access that it’s more aggressive about going back to sleep… but that’s just an observation from N=1.

could be - i didn’t check it in every situation but i know i was sitting on a recording screen and the server would fall asleep until i clicked “watch”. do i need a newer version of the tvOS app? i think i am just running the App Store version rather than a TestFlight build.

App Store build is fine. I’ll try to run some more tests tomorrow, but as soon as I open the app I see the assertion added here.

maybe i should reboot my atv just for good measure… dunno. things could be in a funny state since the backend kept disappearing on the app.

Restarting the app couldn’t hurt. Click TV/Home button twice and swipe up.

Was doing some more digging here and came across https://forums.plex.tv/discussion/169307/perfecting-my-pms-setup-with-wake-sleep/p1 which describes a very similar issue:

The problem under the current energy saver settings in Mac, is that when a client starts playing a file at 12:00, the PMS tells my Mac to remain awake (pmset NoIdleSleep assertion) for as long as the stream is active. However, if the stream is stopped at 12:20, the Mac immediately goes to sleep because it’s past its 15 minutes.

After spending way too long in the macOS documentation, I think I figured out the correct way to implement this, using a combination of assertions.

First, I changed NoIdleSleep to PreventUserIdleSystemSleep. I think they’re actually identical, but the docs say the former is deprecated.

Second I added an activity assertion, which effectively extends the idle timeout. I was going to use NetworkClientActive, but the docs say that if you want to be able to use the GPU (which we need for hardware transcoding) the preferred assertion is UserIsActive with the UserRemote flag. Hopefully passing that extra “Remote” flag means the display will remain off.

Here’s a new build with these changes. Also fixes the bug where recording playback via web was not preventing sleep.

curl -XPUT http://127.0.0.1:8089/updater/check/2017.04.28.0643

semantically “UserIsActive” with UserRemote seems proper, at least. my mac mini is connected to the same television as my appleTV, so i won’t be able to tell if the display is on or not.

i’ll try this build now but won’t have a lot of time to test until this afternoon.

rob

ok - i see those assertions. i rebooted the appleTV and put the server to sleep. upon the atv booting back up, i went into the channels app. the server wakes, but the tvOS app never sees the DVR. however, something must have happened since i see the assertion:

pid 9933(channels-dvr): [0x0000000a00001edd] 00:14:03 UserIsActive named: "DVR Client Activity"

however as you can see there’s no “UserRemote” flag. if i quit out of the tvOS app and go back in, the backend is detected immediately, and now the assertions look like so:

   pid 9933(channels-dvr): [0x0000000100001f70] 00:00:05 PreventUserIdleSystemSleep named: "DVR Engine Activity" 
   pid 9933(channels-dvr): [0x0000000a00001edd] 00:17:07 UserIsActive named: "DVR Client Activity" 

additionally there is a bunch of mdns traffic from the appleTV when it finds the backend, but the first time through it is silent.

Cool, so it works once you leave and enter the app a second time. Presumably now the Mac stays awake for longer and you have no issues watching different recordings?

I’ll see if I can tweak some timeouts to make the first launch work…

i didn’t get a chance to test the longevity of the wake - i’ll have to do that later this afternoon…

rob

I set my Mac Mini to sleep after 1 minute today and did a bunch of testing.

There’s a couple bugs and timeouts in the tvOS app that need to be fixed, but after that it works pretty seamlessly. The mac boots up as soon as you try to use the app and stays alive as long as you’re using it.