10.5: A python script to work around a sleep issue
Sun, Dec 23 2007 at 10:30AM PST • Contributed by: Anonymous

After installing Leopard, my iMac would no longer auto sleep. It worked flawlessly in Tiger. I searched google and found many others having similar problems. I found many different fixes, such as removing the PowerManagement plist file, unplugging all devices, and not running certain widgets or programs. However, no matter what I did, it would not auto sleep. It would stay asleep if I manually put it to sleep.
I called Apple and was on the phone with them for about two hours before they said it is probably a hardware problem, thanks for calling. After all that hassle, I decided to see if AppleScript could put it to sleep, and it did. Once I found that out, I just wrote a python program that keeps track of how long the screen saver is running. Using that, it determines if the system has been unused for the period the user set in system preferences for machine sleep.
import sys, os, shutil, filecmp, string, datetime, time
# initalize some variables
cronPeriod = 1
sleepFile = "/Library/Preferences/SystemConfiguration/com.apple.PowerManagement.plist"
saverFile = os.path.join(os.getenv("HOME")) + '/Library/Preferences/ByHost/com.apple.screensaver.0016cb98e9e2'
trackingFile = os.path.join(os.getenv("HOME")) + '/var/sleepTracker'
f = open(sleepFile, "r")
useNextLine = 0
for line in f.readlines():
if useNextLine == 1:
useNextLine = 0
timeLine = line.strip()
if line.strip() == "<key>System Sleep Timer</key>":
useNextLine = 1
f.close()
sleepTime = timeLine.strip('<integer>')
sleepTime = sleepTime.strip('</')
sleeepTime = int(sleepTime)
screensaverTime = os.popen("defaults read " + saverFile + " idleTime")
screensaverTime = screensaverTime.read()
sleepTime = int(sleepTime) * 60 - int(screensaverTime)
if sleepTime < 0:
sleepTime = 0
########################################
# Begin function definations
########################################
# checkFiles is the function that checks the times
# of the tracking file
def clearFile():
if os.path.exists(trackingFile):
os.remove(trackingFile)
cmd = "touch " + trackingFile
os.system(cmd)
def compareTimes():
endLine = ""
currentTime = time.mktime(datetime.datetime.now().timetuple())
currentTime = str(currentTime).split('.')[0]
f = open(trackingFile, "r")
data = f.read()
f.close()
lines = data.split("n")
lastRunning = lines[len(lines)-2]
lastRunning = lastRunning.split('.')[0]
if lastRunning == "":
print "last time is: " + lastRunning
return
difference = int(currentTime) - int(lastRunning)
print time.localtime()
print "difference between current time and last time saver was found running is: ", difference
cronPeriodSec = int(cronPeriod * 1.5 * 60)
print time.localtime()
print "cron period is: ", cronPeriodSec
if difference > cronPeriodSec:
print time.localtime()
print "difference is greater - need to clear file"
clearFile()
def wantSleep(currentTime):
f = open(trackingFile, "r")
data = f.read()
f.close()
lines = data.split("n")
firstRunning = lines[0]
firstRunning = firstRunning.split('.')[0]
if firstRunning == "":
#print "firstRunning was blank"
return
print "current time is: ", currentTime, " first time is: ", firstRunning
difference = int(currentTime) - int(firstRunning)
print time.localtime()
print "difference between now and first time screensaver was on is: ", difference
print "comparing against: ", int(sleepTime)
if difference >= sleepTime:
print time.localtime()
print "sleep is desired"
aplcmd = 'tell app "Finder" to sleep'
cmd = "/usr/bin/osascript -e " + "'" + aplcmd + "'"
print time.localtime()
print cmd
os.system(cmd)
##############################################
# End function definations
#############################################
#check if the screensaver is running:
cmd = "ps -e | grep ScreenSaverEngine | grep -v grep"
result = os.system(cmd)
#print "remove the following line to run for real"
#result = 234
if result != 256:
print time.localtime()
print "Screen Saver is running"
compareTimes()
currentTime = time.mktime(datetime.datetime.now().timetuple())
currentTime = str(currentTime).split('.')[0]
f = open(trackingFile, 'a')
f.write(currentTime + "n")
f.close
wantSleep(currentTime)
else:
print time.localtime()
print "Screen Saver Not running"
clearFile()
sys.exit(1)
I put this in
cron to run once a minute and it has been working very reliably. Note: I didn't make it robust enough to find the screensaver preferences file. I hard-coded it to mine, so if anyone wants to try it, you would need to update the numbers at the end of the
saverFile value.
[
robg adds: I haven't tested this one.]