使用Python防止OS X进入睡眠状态?

10

有没有一种方法可以在Python脚本内防止运行OS X的计算机进入睡眠状态?


虽然不是编程答案,但Caffeine是一个很好的免费应用程序,可以在激活时防止您的计算机进入睡眠模式。 - Alex
谢谢@Alex,我遇到过几个可以做到这一点的应用程序,但是从脚本内部执行会更加简洁。 - christianbrodbeck
5个回答

12

您可以使用内置的caffeinate命令。

subprocess.Popen('caffeinate')

这是我使用它的方法:

import sys
import subprocess

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

在Python中,当进程完成后,如何退出咖啡因模式呢? - undefined

5

你还可以在外部终端窗口中运行caffeinate并保持其打开,以实现OP想要的功能。

  1. 打开终端

  2. 键入caffeinate

  3. 按下Enter

这样做后,你的Mac将保持清醒状态,直到你关闭该终端。

你可以将其最小化或隐藏,你的Mac将不会进入睡眠模式,直到你使用键盘快捷键Ctrl+C来中断命令。

来源


3
自从OS 10.6版本,你需要使用Cocoa中提供的IOPMAssertion函数族。这个网站详细解释了如何正确地使用。
然后,你需要在Python中调用它。我不确定是否已经有特定的Python绑定Cocoa的库,但是你可以调用Objective-C函数。这个网站详细描述了如何做到这一点。

那么,这将涉及使用ctypes来实现qa1340的第2个清单吗?有相关的说明吗?(例如,我如何检索诸如kIOPMAssertionTypeNoDisplaySleep之类的值?) - christianbrodbeck

0

appnope 是用于防止 App Nap 而非系统休眠的。请参见:https://github.com/minrk/appnope/blob/daac76517da8aba6fd0614eb1ab37d9b8ee39633/appnope/_nope.py#L78 - UloPe
只需在代码中再往上看一点,就能找到其他常量。 - christianbrodbeck
是的,常量已经存在,但功能没有通过记录在案的“nope()”API公开。 - UloPe

0
另一种选择是使用以下脚本运行
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

要保存在本地的脚本:

#!/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)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接