Keep the screen awake while script (app) running

Hello,

I assumed that the following script, run as a stay-open application, would keep the screen and computer awake, but for some reason they fall asleep after the 1st minute (setting in the system power settings).

Apparently I missed something? Or is the caffeinate utility no longer working? It’s like a built-in Mac OSX utility. I have Catalina.
.

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use framework "AppKit"
use scripting additions

on run
	addObserver("screensDidSleepNotification:", "NSWorkspaceScreensDidSleepNotification")
	-- addObserver("workspaceWillSleepNotification:", "NSWorkspaceWillSleepNotification")
end run

on addObserver(selectorHandler, notificationName)
	set aCenter to current application's NSWorkspace's sharedWorkspace()'s notificationCenter()
	aCenter's addObserver:me selector:selectorHandler |name|:notificationName object:(missing value)
end addObserver

on workspaceWillSleepNotification:aNotif
	do shell script "caffeinate -u -t 60"
end workspaceWillSleepNotification:

on screensDidSleepNotification:aNotif
	do shell script "caffeinate -u -t 60"
end screensDidSleepNotification:

I found 2 problems:

  1. caffeinate as part of the script works, but only in a special way,
  2. NSWorkspace does not catch system notifications about falling asleep on the workspace and screens (“NSWorkspaceScreensDidSleepNotification” and “NSWorkspaceWillSleepNotification”.

The problem is that there is no information on the web about this (in connection with AppleScript) at all. In short, the 2nd problem is unsolvable, the observer is useless and I abandoned it altogether.

The following script works as it should. It should be tested as an usual application for the purity of the experiment, but you can use this trick in any other forms as well. The caffeinate time should be setted bigger than the app or script execution time (you can set 3600, a hour, for example):
.

do shell script "caffeinate -u -t 180 > /dev/null 2>&1 &" -- 3 minutes to not sleep

repeat 2 times -- test, 2 min to execute  (setting for disply sleep = 1 min in Power Manager)
	delay 60
end repeat

.
One cleaner script should kilall the caffeinate process at the end of script.

The point of this test is that without the 1st line of code, the screen would go to sleep about a 1 minute after the application was launched. And so it does not fall asleep, while the application is executed for about 2 minutes.

Other approach is using pmset command to set/reset the displaysleep time, but this requires the user password inserting.

Returning to the topic. Killing a caffeinate process after script stuff executed is very easy with the killall shell command:
.

do shell script "caffeinate -u -t 36000 > /dev/null 2>&1 &" -- big number, 10 hours to not sleep here

---
delay 5 -- do stuff like this
---

try
	do shell script "killall 'caffeinate'"
end try
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

property theTask : missing value

my startPreventFromSleep()
-------
delay 60 -- do what you want…
-------
my stopPreventFromSleep()

on startPreventFromSleep()
	my stopPreventFromSleep()
	set theTask to current application's NSTask's new()
	theTask's setLaunchPath:"/bin/sh"
	theTask's setArguments:{"-c", "caffeinate -i"}
	theTask's |launch|()
end startPreventFromSleep

on stopPreventFromSleep()
	if theTask is not missing value then
		if (theTask's isRunning() as boolean) then
			theTask's terminate()
		end if
	end if
end stopPreventFromSleep

@Fredrik71,

it is useful info, but I want the “none sleep” state to terminate after script execution automatically. I can move and restore the mouse after script execution, but that requires Python or AsObjC. My solution is plain AppleScript.

The info is not correct. The default settings do not prevent the monitor from going off or the sleep mode. Not even when Mission Control is displayed (tested with Monterey and Ventura) and there is no setting for the corners that would indicate this. You can only disable the screen saver.

1 Like

That may be, but by doing so you do not change the system’s energy saving settings (pmset) and prevent the display from being switched off at some point and the computer from going into sleep mode.
The script execution will be interrupted in the latter case and I think that’s what it’s all about.