web-dev-qa-db-ja.com

スリープモードを防ぐpython(Python上のワイクロック)

異なるOS上の追加のアプリを使用せずにpythonのスリープモードを防止する方法(Ubuntu、Windows ...)ではほとんどの場合、Linuxソリューションが必要です。

私は大量の時間に働くアプリを作っています。それはCPUの80%のように使用されるので、ユーザーはこのアプリを起動してキーボードから離れるだけです。だから私はスリープモードをロックするシステムAPIやライブラリのようなものが必要だと思います。私はそれが存在すると確信しています。たとえば、OS上のビデオプレーヤーを開くと、(PC、ラップトップ)はスリープモードにはなりません。ブラウザでは同じことがあります。

また、Android( wakelock )またはwindows (setthreadexecationState) と同じことがあります。

6
Max Dev

Windowsが目覚めさせるために作成されたサンプルTKアプリケーション

import tkinter as tk
import ctypes
import sys

def display_on():
    print("Always On")
    ctypes.windll.kernel32.SetThreadExecutionState(0x80000002)

def display_reset():
    ctypes.windll.kernel32.SetThreadExecutionState(0x80000000)
    sys.exit(0)


root = tk.Tk()
root.geometry("200x60")
root.title("Display App")
frame = tk.Frame(root)
frame.pack()

button = tk.Button(frame,
                   text="Quit",
                   fg="red",
                   command=display_reset)
button.pack(side=tk.LEFT)
slogan = tk.Button(frame,
                   text="Always ON",
                   command=display_on)
slogan.pack(side=tk.LEFT)

root.mainloop()
 _
2
Devil

私がインターネット全体を通して見つけた複数のアプローチに基づいて、私は以下のこのモジュールを思い付きました。 Windows回避策のための@Mishsxに感謝します。

それを使うことは非常に単純です。コンテキストマネージャとして、_standby_lock_またはStandbyLockを使用してデコレータアプローチを選ぶことができます。

_## decorator
@standby_lock
def foo(*args, **kwargs):
    # do something lazy here...
    pass

## context manager
with StandbyLock():
    # ...or do something lazy here instead
    pass
_

fooが実行中ですが、システムは起きています。

注:LinuxSudo特権と_OS X_(Darwin)が必要なので、まだいくつかの注意事項があります。

_from functools import wraps
import platform

class MetaStandbyLock(type):
    """
    """

    SYSTEM = platform.system()

    def __new__(cls, name: str, bases: Tuple, attrs: dict) -> type:
        if not ('inhibit' in attrs and 'release' in attrs):
            raise TypeError("Missing implementations for classmethods 'inhibit(cls)' and 'release(cls)'.")
        else:
            if name == 'StandbyLock':
                cls._superclass = super().__new__(cls, name, bases, attrs)
                return cls._superclass
            if cls.SYSTEM.upper() in name.upper():
                if not hasattr(cls, '_superclass'):
                    raise ValueError("Class 'StandbyLock' must be implemented.")
                cls._superclass._subclass = super().__new__(cls, name, bases, attrs)
                return cls._superclass._subclass
            else:
                return super().__new__(cls, name, bases, attrs)

class StandbyLock(metaclass=MetaStandbyLock):
    """
    """

    _subclass = None

    @classmethod
    def inhibit(cls):
        if cls._subclass is None:
            raise OSError(f"There is no 'StandbyLock' implementation for OS '{platform.system()}'.")
        else:
            return cls._subclass.inhibit()

    @classmethod
    def release(cls):
        if cls._subclass is None:
            raise OSError(f"There is no 'StandbyLock' implementation for OS '{platform.system()}'.")
        else:
            return cls._subclass.release()

    def __enter__(self, *args, **kwargs):
        self.inhibit()
        return self

    def __exit__(self, *args, **kwargs):
        self.release()

class WindowsStandbyLock(StandbyLock):
    """
    """

    ES_CONTINUOUS      = 0x80000000
    ES_SYSTEM_REQUIRED = 0x00000001

    INHIBIT = ES_CONTINUOUS | ES_SYSTEM_REQUIRED
    RELEASE = ES_CONTINUOUS

    @classmethod
    def inhibit(cls):
        import ctypes
        ctypes.windll.kernel32.SetThreadExecutionState(cls.INHIBIT)

    @classmethod
    def release(cls):
        import ctypes
        ctypes.windll.kernel32.SetThreadExecutionState(cls.RELEASE)

class LinuxStandbyLock(metaclass=MetaStandbyLock):
    """
    """

    COMMAND = 'systemctl'
    ARGS = ['sleep.target', 'suspend.target', 'hibernate.target', 'hybrid-sleep.target']

    @classmethod
    def inhibit(cls):
        import subprocess
        subprocess.run([cls.COMMAND, 'mask', *cls.ARGS])

    @classmethod
    def release(cls):
        import subprocess
        subprocess.run([cls.COMMAND, 'unmask', *cls.ARGS])

class DarwinStandbyLock(metaclass=MetaStandbyLock):
    """
    """

    COMMAND = 'caffeinate'
    BREAK = b'\003'

    _process = None

    @classmethod
    def inhibit(cls):
        from subprocess import Popen, PIPE
        cls._process = Popen([cls.COMMAND], stdin=PIPE, stdout=PIPE)

    @classmethod
    def release(cls):
        cls._process.stdin.write(cls.BREAK)
        cls._process.stdin.flush()
        cls._process.stdin.close()
        cls._process.wait()

def standby_lock(callback):
    """ standby_lock(callable) -> callable
        This decorator guarantees that the system will not enter standby mode while 'callable' is running.
    """
    @wraps(callback)
    def new_callback(*args, **kwargs):
        with StandbyLock():
            return callback(*args, **kwargs)
    return new_callback
_
1
Pedro

Keep.awakeのロジックは、UbuntuまたはLinux Distro Running Gnome(旧と新しいUnity)の問題を解決するため、WaylandとXの両方で動作します。使いやすいです。

私はここで似たような質問に解決策を投稿しました: https://unkubunubuntu.com/a/1231975/183131

そのため、次のようにします。

  1. Subprocess.popen(...)を介してdbusコマンドを使用して、スリープ/サスペンドカウンタをクリアします。
  2. Psutil.cpu_percent()を使用して、CPU使用量を定期的に照会するか、またはプログラムが完了したら、SLEEP CONFIGを再設定したことを実行したら、ロジックを入力します。

あなたはあなたのコードを修正する方法についての詳細やヒントについてここでコードを見ることができます: https://launchpad.net/keep.awake

あるいは、CPU集中型プログラムを実行しているLinuxボックスでkeepawake.pyを実行するだけで、問題を解決します。うまくいく!

Webページからの使用例:

バックグラウンドサービスとして実行し、最小CPU負荷を13%として設定するには:

Nohup ./keepawake.py -c 13 -r > /dev/null 2>&1 &
 _

バックグラウンドサービスとして実行し、ユーザーがアイドル状態であると判断する前にユーザーアクティビティアイドル時間として15分(900秒)を設定します。

Nohup ./keepawake.py -u 900 -r > /dev/null 2>&1 &
 _

背景サービスとして実行し、最小ネットワークトラフィックを5KB(5120バイト)に設定するには、次の手順を実行します。

Nohup ./keepawake.py -s 5120 -r > /dev/null 2>&1 &
 _

バックグラウンドサービスとして実行し、スケジュールを1時間以降にスリープ/サスペンドするように設定するには(この値はすべて設定されている場合にのみ設定されます)。

Nohup ./keepawake.py -w 3600 -r > /dev/null 2>&1 &
 _

上記のすべての設定(ネットワーク、CPU、ユーザーアイドル、スリープスケジュール)を実行するには、詳細な出力で「/home/eduser/sleep/log/keep.awake/」にログファイルパスを設定します。

Nohup ./keepawake.py -s 5120 -c 13 -u 900 -w 3600 -l /home/$USER/sleep/log/Keep.Awake/ -v Detail -r > /dev/null 2>&1 &
 _
1
DanglingPointer

Winky:

グーグルの中に、タスクの実行中にWindowsが眠っているのを防ぐために、 SetThreadExecutionState を使用してたくさんの人が見つかりました。利用可能なパッケージはありませんでしたので、Pypiに入れるためにパッケージ化することにしました。 wakepy

Cl

python -m wakepy [-s]
 _

オプションの_を使う-sフラグも画面を維持します。

Python Api

from wakepy import set_keepawake, unset_keepawake

set_keepawake(keep_screen_awake=False)
# do stuff that takes long time
unset_keepawake()
 _
0
np8