How to put a Mac to sleep after display disconnect using AppleScript?

I would like to solve the issue from this question, namely, after disconnecting a Cinema display from a clamshell MacBook I would like to let the MacBook go to sleep without opening and closing the lid.

I have never used AppleScript before. Is it possible to write an AppleScript which puts the computer to sleep, say 30 seconds after disconnect of an external display, but only if the lid is closed.


Using the included Script Editor.app with OS X, try experimenting with these snippets.

Wait 30 Seconds

The following snippet will make your script wait 30 seconds before showing a dialog:

delay 30 -- this waits thirty seconds
display dialog "Hello?" -- this shows a dialog

Sleep

The following snippet will put your Mac immediately to sleep:

tell application "System Events"
    sleep
end tell

Wait and then Sleep

Combining the two snippets above gives an AppleScript that will wait 30 seconds before putting your Mac to sleep:

delay 30
tell application "System Events"
    sleep
end tell

Displays and Desktops

I am not sure how best to determine if a monitor is connected. You could certainly poll regularly; calling system_profiler SPThunderboltDataType SPDisplaysDataType and parsing the output would work.

Polling is computationally expensive and best avoided.

Alternatively, maybe an approach whereby an AppleScript could determine if the number of active desktops has changed? When two monitors are connected to my Mac, the following snippet returns a two item list:

tell application "System Events"
    set myDesktops to desktops
end tell

Expanding on this, the following snippet provides more display information to work with:

tell application "System Events"
    set myDesktop to properties of the first desktop
end tell

I'm not going to pretty this up like Graham Miln nicely did however it you want to create an AppleScript app that you can run before disconnecting your external display then this will wait 30 seconds, check to see if it's in clamshell mode and if yes put the system to sleep.

AppleScript code:

delay 30
set AppleClamshellState to do shell script "ioreg -r -k AppleClamshellState -d 1 | awk -F' = ' '/AppleClamshellState/ {print $2}'"
if AppleClamshellState = "Yes" then tell application "Finder" to sleep

Note: In the if statement, System Events can be use in place of Finder as either will accept the sleep command.