christianbrodbeck
christianbrodbeck

Reputation: 2210

Prevent OS X from going to sleep with Python?

Is there a way to prevent a computer running OS X from going to sleep from within a Python script?

Upvotes: 13

Views: 11289

Answers (5)

asdf
asdf

Reputation: 67

Another alternative would be to run the below script with

python <location/of/my/script.py> <hour until I want the PC to be awake>
e.g.
python /Users/johndee/Downloads/keep_awake.py 18:30

The script, which is to be saved locally:

#!/usr/bin/env python3
import random
import sys
import time
from datetime import datetime
from tkinter import Tk

import pyautogui

CHECK_STATUS_ONCE_IN = 120
WAIT_FOR_POSITION_CHANGE = 10


def current_position():
    tkinter = Tk()
    return [tkinter.winfo_pointerx(), tkinter.winfo_pointery()]


def mouse_is_moving():
    pos1 = current_position()
    time.sleep(WAIT_FOR_POSITION_CHANGE)
    pos2 = current_position()
    return not pos1 == pos2


def keep_awake():
    # Shake the mouse a lil bit
    initial_x, initial_y = current_position()
    try:
        for _ in range(random.randint(1, 10)):
            # Mouse
            pyautogui.moveTo(random.randint(1, 1000), random.randint(1, 1000))

            # Keys
            pyautogui.press("shift")

        # Restore controls
        pyautogui.moveTo(initial_x, initial_y)
    except pyautogui.FailSafeException as e:
        print(e)


def inspect_activity_until(time_to_stop: datetime):
    time_to_stop = datetime.now().replace(
        hour=time_to_stop.hour, minute=time_to_stop.minute
    )
    while datetime.now() < time_to_stop:
        if not mouse_is_moving():
            keep_awake()
        time.sleep(CHECK_STATUS_ONCE_IN)

    print(f"Stopping at {datetime.now()}")


if __name__ == "__main__":
    given_time = sys.argv[1]
    date_time_obj = datetime.strptime(given_time, "%H:%M")
    inspect_activity_until(date_time_obj)

Upvotes: 0

JacoSolari
JacoSolari

Reputation: 1404

You can also run caffeinate in an external terminal window and leave it open to achieve what the OP wants.

  1. open a terminal

  2. type caffeinate

  3. press Enter

Once you have done this, your Mac will stay awake for as long as you leave the Terminal running.

You can minimize or hide it, and your Mac will not go to sleep until you use the keyboard shortcut Ctrl+C to interrupt the command.

source

Upvotes: 6

guya
guya

Reputation: 5260

You can use the built-in caffeinate command.

subprocess.Popen('caffeinate')

This is how I use it:

import sys
import subprocess

if 'darwin' in sys.platform:
    print('Running \'caffeinate\' on MacOSX to prevent the system from sleeping')
    subprocess.Popen('caffeinate')

Upvotes: 13

christianbrodbeck
christianbrodbeck

Reputation: 2210

There is a Python utility that illustrates how to raise the required assertions in Python directly: https://github.com/minrk/appnope

Upvotes: 0

dasilvj
dasilvj

Reputation: 10396

Since OS 10.6, you have to make use of the IOPMAssertion family of functions, available in Cocoa. This is really well explained there.

Then, you will have to call it from Python. I'm not sure that there're already specific bindings for Cocoa in Python, but you can call Objective-C functions. It is really well described here.

Upvotes: 3

Related Questions