I don't want my machine shutdown because of out of battery because I may get the issues such as losing unsaved tasks and my hard drive is not mounted when the machine starts again. The Energy Saver settings in Mac OS X can put my machine to sleep after it has been idled for a period of time but it can't help in my case because most of the time I leave the music player app running so my machine is never idle.
Thus, I created an AppleScript that automatically put my machine to sleep when the battery is lower than %15. The script will be executed every 3 minutes by a cron job. For info, I'm using Mac OS X Mountain Lion 10.8.
1. Create the Apple script
Open AppleScript Editor and insert the following code and save it as SleepWhenLowBattery.scpt in /Applications/MyApps/ directory.
property lowBattery : 15
set battStatus to do shell script "pmset -g ps"
if battStatus contains "Battery Power" then
set {TID, text item delimiters} to {text item delimiters, ";"}
set battStatus to text items of battStatus
set text item delimiters to tab
set battStatus to text 1 thru -2 of last text item of item 1 of battStatus as integer
set text item delimiters to TID
if battStatus < lowBattery then
tell application "Finder"
activate
set alertResult to display alert ¬
"Low battery! Your machine is going to sleep in 90 seconds..." buttons {"Cancel", "Sleep Now"} as warning ¬
default button ¬
"Cancel" cancel button ¬
"Cancel" giving up after 90
if gave up of alertResult then
do shell script "pmset sleepnow"
else if button returned of alertResult is "Sleep Now" then
do shell script "pmset sleepnow"
end if
end tell
end if
end if
return 60
This script checks the current battery status. If it's lower than the defined value, it displays an alert saying that the machine is going to sleep in 90 seconds and the user can choose to sleep now or cancel.
Below is the sample output of the command '
pmset -g ps' while charging:
$ pmset -g ps
Currently drawing from 'AC Power'
-InternalBattery-0 60%; charging; (no estimate)
Below is the sample output of the command '
pmset -g ps' while discharging:
$ pmset -g ps
Currently drawing from 'Battery Power'
-InternalBattery-0 61%; discharging; (no estimate)
So, the script will put your computer into sleep only if your machine is not charging.
Another note about the script is that the code to display the alert need to be put in
'tell application "finder"' block or you'll get the error message below logged by the cron job in
/var/mail/${username} file. Without that block, the script can still be executed manually by the user from Terminal.
/Applications/MyApps/SleepWhenLowBattery.scpt: execution error: No user interaction allowed. (-1713)
2. Create a cron job to run the script every 3 minutes
Open Terminal and type:
crontab -e
It will open crontab configuration file in VI editor. And then press 'I' key to be able to write into the file and insert the following line.
*/3 * * * * osascript /Applications/MyApps/SleepWhenLowBattery.scpt
After that, press 'Esc' key and type ':wq' to save change and quit the VI editor. Please note that the cron job running interval should be greater than the waiting time before machine sleeps (90 seconds) defined in the script above or you will get more than one alerts on your screen if you don't close them. This cron job does not run for all users; it's for the current user only.
Now, you're done; you DON'T need to restart your machine or logout.
References
https://discussions.apple.com/thread/3836771
http://stackoverflow.com/questions/13484482/no-user-interaction-allowed-when-running-applescript-in-python