Reputation: 339
How I can prevent sleep-mode on python without using extra apps on different OS(Ubuntu, Windows...) but in most cases I need Linux solution
I am making app that works big amount of time. It uses like 80% of CPU, so a user just start this app and go away from keyboard. So I think I need something like system api or library that lock sleep-mode. I am sure that, it exists. For example, if you open any video player on your OS, your (PC, Laptop) will not go to sleep mode, the same thing in browser.
Also, there is the same thing in Android (WakeLock) or Windows (SetThreadExecutionState)
Upvotes: 23
Views: 37674
Reputation: 560
I've written this Python Code that doesn't only keep your screen active but also let's you work without disturbing you. Basically, You don't have to turn it on and off. You can keep it running and work at the same time -
Here's the python code - https://github.com/sudhanshuism/keepPCAliveUserEnabled
Upvotes: 0
Reputation: 33770
While googling around to find a solution there was no package available, so I decided to package it to put it to PyPI: wakepy. I got PRs for cross-platform support, and currently wakepy supports Windows, Linux and macOS.
python -m wakepy [-p]
Using the optional -p
flag will use a presentation mode, which keeps the screen on & unlocked.
Prevent sleep:
from wakepy import keep
with keep.running():
# do stuff that takes long time
Prevent screensaver/screen lock (and sleep):
from wakepy import keep
with keep.presenting():
# do stuff that takes long time
Upvotes: 22
Reputation: 81
This code is used to move mouse cursor after every n minutes to keep the system awake.
First install pyautogui
for Python.
Run the following code:
import pyautogui
import time
import sys
from datetime import datetime
pyautogui.FAILSAFE = False
numMin = None
if ((len(sys.argv)<2) or sys.argv[1].isalpha() or int(sys.argv[1])<1):
numMin = 2 # move cursor after numMin minutes
else:
numMin = int(sys.argv[1])
while(True):
x=0
while(x<numMin):
time.sleep(60)
x+=1
for i in range(0,50):
pyautogui.moveTo(i*6+50,i*4)
pyautogui.moveTo(1,1)
for i in range(0,3):
pyautogui.press("shift")
print("Movement made at {}".format(datetime.now().time()))
Upvotes: 2
Reputation: 1174
Python3
install library
pip install pywin32
save below code as alive.pyw
file
from ctypes import windll, wintypes, byref, c_uint, sizeof, Structure
import tkinter as tk
import ctypes
import sys
import threading
import time
import win32api
import win32con
stop_threads = True
SET_IDLE_TIME = 40 #in seconds
class LASTINPUTINFO(Structure):
_fields_ = [
('cbSize', c_uint),
('dwTime', c_uint),
]
def get_idle_duration():
lastInputInfo = LASTINPUTINFO()
lastInputInfo.cbSize = sizeof(lastInputInfo)
windll.user32.GetLastInputInfo(byref(lastInputInfo))
millis = windll.kernel32.GetTickCount() - lastInputInfo.dwTime
return millis / 1000.0
def press_key_2():
global stop_threads
while True:
if not stop_threads:
break
idle_time = get_idle_duration() #seconds
time.sleep(0.1)
if idle_time < SET_IDLE_TIME:
continue
print("in ideal state pressing cltr")
win32api.keybd_event(ord('x'), 0, win32con.KEYEVENTF_EXTENDEDKEY, 0)
#---------------- Monitor threads ------------------------------
t1 = threading.Thread(target=press_key_2, name='t1')
t1.daemon = True
#----------------- TK functions ----------------------
def display_on():
global tk, t1, stop_threads
stop_threads = True
print("Always On")
ctypes.windll.kernel32.SetThreadExecutionState(0x80000002)
root.iconify()
t1.start()
# t2.start()
def display_reset():
print("quit pressed")
global stop_threads
stop_threads = False
ctypes.windll.kernel32.SetThreadExecutionState(0x80000000)
sys.exit(0)
root = tk.Tk()
root.geometry("200x110")
root.title("Display App")
frame = tk.Frame(root)
frame.pack()
var = tk.StringVar()
label = tk.Label(frame, textvariable = var)#, bd = 5, justify = tk.RIGHT, padx = 10, pady = 10)
var.set("")
button = tk.Button(frame,
text="Quit",
fg="red",
command=display_reset)
slogan = tk.Button(frame,
text="Always ON",
command=display_on)
label.pack(side=tk.BOTTOM,padx=0, pady=0)
slogan.pack(side=tk.LEFT,padx=15, pady=20)
button.pack(side=tk.LEFT,padx=15, pady=20)
root.mainloop()
ctypes.windll.kernel32.SetThreadExecutionState(0x80000000)
Upvotes: 0
Reputation: 1
On Windows, not sure if this will help anyone, but the above didn't work for me. What finally worked was running 2nd process that just keeps calling "shutdown /a" (abort shutdown) every 30 sec. Windows says you have approx. ~1 min to do this so that's why the 30 seconds.
Totally stupid solution, but this is a pretty dumb problem to not have an os-provided solution anyway.
import subprocess
from time import sleep
def main():
while(True):
p = subprocess.Popen("shutdown /a", stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
res = p.communicate()
p.kill()
sleep(30) # sleep 30 sec.
if __name__ == "__main__":
main()
Upvotes: 0
Reputation: 11
You can also use Caffeine+, it's a tiny tray application that keeps the system awake without simulate keyboard events or interfering with the ui at all. https://enemydevelopment.com/software/caffeine
Upvotes: 0
Reputation: 1174
Created sample TK application to keep windows awake
import tkinter as tk
import ctypes
import sys
def display_on():
global root
print("Always On")
ctypes.windll.kernel32.SetThreadExecutionState(0x80000002)
root.iconify()
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()
Upvotes: 10
Reputation: 3856
I created a package for it called stay-awake
PyPi: https://pypi.org/project/stay-awake/
Github: https://github.com/singhsidhukuldeep/stay-awake
Stay-Awake is a Simple Platform Independent Python package to keep your system awake without affecting workflow!
No, this only get's triggered when you don't do any mouse movements!
This was intended to be a light weight solution, so as of now it only has a CLI!
If in a span of 60 seconds you don't move your mouse, this script will automatically move your mouse for about 1 to 4 pixels randomly. There won't be any mouse displacement! If you are working, this will do absolutely nothing!
pip3 install stay-awake
python3 -m stay-awake
You can also give custom timeouts Eg: for 5 minutes (default is 1 min)
python3 -m stay-awake 5
Upvotes: 5
Reputation: 1121
Based on multiple approaches I've found throughout the internet I've come up with this module below. Special thanks to @mishsx for the Windows
workaround.
Using it is very simple. You may opt for the decorator approach using standby_lock
or via StandbyLock
as a context manager:
## decorator
@standby_lock
def foo(*args, **kwargs):
# do something lazy here...
pass
## context manager
with StandbyLock():
# ...or do something lazy here instead
pass
While foo
is executing, your system will stay awake.
Note: There are still some caveats, as Linux
may require sudo
privileges and OS X
(Darwin
) is not tested yet.
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
Upvotes: 3
Reputation: 1015
The logic in Keep.Awake will solve your problem on ubuntu or any Linux Distro running Gnome (old and new including Unity), works on both Wayland and X. It is easy to use.
I posted a solution to a similar question here: https://askubuntu.com/a/1231975/183131
So logic-wise do the following:
You can view the code here for details or hints on how you can mod your code: https://launchpad.net/keep.awake
Alternatively you can just run keepawake.py on the Linux box you're running your cpu-intensive program on and it will solve your problem! It just works!
Example usage taken from the webpage:
To run as background service and set minimum CPU load as 13%:
nohup ./keepawake.py -c 13 -r > /dev/null 2>&1 &
To run as background service and set 15 min (900 sec) as the user activity idle time before it determines that the user is idle:
nohup ./keepawake.py -u 900 -r > /dev/null 2>&1 &
To run as background service and set minimum network traffic as 5KB (5120 bytes):
nohup ./keepawake.py -s 5120 -r > /dev/null 2>&1 &
To run as background service and set the schedule to sleep/suspend after 1 hour (this value is only set if user-activity, cpu, and network traffic are all determined to be idle) :
nohup ./keepawake.py -w 3600 -r > /dev/null 2>&1 &
To run all settings above (network, CPU, User idle, sleep schedule) in the one go and set the log-file path to "/home/$USER/sleep/log/Keep.Awake/" with detailed output:
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 &
Upvotes: 2
Reputation: 1490
I ran into similar situation where a process took long enough to execute itself that windows would hibernate. To overcome this problem I wrote a script.
The following simple piece of code can prevent this problem. When used, it will ask windows not to sleep while the script runs. (In some cases, such as when the battery is running out, Windows will ignore your request.)
class WindowsInhibitor:
'''Prevent OS sleep/hibernate in windows; code from:
https://github.com/h3llrais3r/Deluge-PreventSuspendPlus/blob/master/preventsuspendplus/core.py
API documentation:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa373208(v=vs.85).aspx'''
ES_CONTINUOUS = 0x80000000
ES_SYSTEM_REQUIRED = 0x00000001
def __init__(self):
pass
def inhibit(self):
import ctypes
print("Preventing Windows from going to sleep")
ctypes.windll.kernel32.SetThreadExecutionState(
WindowsInhibitor.ES_CONTINUOUS | \
WindowsInhibitor.ES_SYSTEM_REQUIRED)
def uninhibit(self):
import ctypes
print("Allowing Windows to go to sleep")
ctypes.windll.kernel32.SetThreadExecutionState(
WindowsInhibitor.ES_CONTINUOUS)
To run the script, simply :
import os
osSleep = None
# in Windows, prevent the OS from sleeping while we run
if os.name == 'nt':
osSleep = WindowsInhibitor()
osSleep.inhibit()
# do slow stuff
if osSleep:
osSleep.uninhibit()
Upvotes: 13