Suspender, hibernar y despertar el sistema



Versión: 2.4+, 3.x.

La función de suspender coloca al ordenador en un estado de bajo consumo de recursos y energía, previo al guardado del estado del sistema en la memoria RAM. Por esta razón, al ser desconectado o apagado, la información guardada se pierde. La función de hibernar, en cambio, almacena el estado del sistema en el disco y se apaga por completo, de modo que, al encenderlo nuevamente, nos encontramos con todo en su lugar (¡el que ocupaba previo al apagado!). Si el sistema no está configurado correctamente o bien el hardware no soporta la función de hibernar, ésta equivale a un apagado convencional.

Sin más preámbulos, ¡veamos algunos sencillos métodos para poner a dormir nuestra computadora!

Linux

La mayoría de las distribuciones de Linux con un entorno de escritorio implementan el comando dbus-send, que resulta bastante agradable al no requerir permisos de administrador.

Utilizamos la función subprocess.call para invocar el comando.

from subprocess import call

# Suspender.
call('dbus-send --system --dest="org.freedesktop.UPower" '
     '--print-reply /org/freedesktop/UPower '
     'org.freedesktop.UPower.Suspend', shell=True)

# Hibernar.
call('dbus-send --system --dest="org.freedesktop.UPower" '
     '--print-reply /org/freedesktop/UPower '
     'org.freedesktop.UPower.Hibernate', shell=True)

Como alternativa puede utilizarse rtcwake, aunque requiere permisos de administrador. Ofrece la ventaja de despertar automáticamente de un estado de suspensión. Por ejemplo, el siguiente código suspende el sistema y lo reanuda luego de 20 segundos.

# Suspender y despertar luego de 20 segundos.
call("rtcwake -s 20 -m mem", shell=True)

De forma similar, la opción -m disk permite hibernar.

Windows

Empleamos la función de la API de Windows SetSuspendState vía el módulo estándar ctypes.

from ctypes import windll

# Suspender.
if not windll.powrprof.SetSuspendState(False, False, False):
    print("No se ha podido suspender el sistema.")

El primer argumento de la función determina si el sistema debe ingresar en estado de suspensión (False) o hibernación (True).

# Hibernar.
if not windll.powrprof.SetSuspendState(True, False, False):
    print("No se ha podido suspender el sistema.")

El sistema puede ser automáticamente despertado luego de un período de tiempo utilizando las funciones CreateWaitableTimer y SetWaitableTimer. Ejemplo:

from ctypes import windll, byref
from ctypes.wintypes import LARGE_INTEGER

timer = windll.kernel32.CreateWaitableTimerW(None, True, None)

if timer:
    # Suspender y despertar luego de 10 segundos.
    if windll.kernel32.SetWaitableTimer(timer,
        byref(LARGE_INTEGER(-100000000)), 0, None, None, True):
        if not windll.powrprof.SetSuspendState(False, False, False):
            print("No se ha podido suspender el sistema.")
    else:
        print("No se pudo crear el timer.")

El segundo argumento de SetWaitableTimer indica el momento en que debe lanzarse el evento para salir de la suspensión y despertar. Se utiliza un número negativo para indicar relatividad, es decir, 10 segundos (expresado en intervalos de 100 nanosegundos, esto es, -segundos * 10000000) a partir del tiempo actual.

¿Qué te parece? Simple, eficaz, ¡y sin módulos de terceros!



Deja un comentario