Manteniendo tu computadora encendida

Estos tiempos de home office me han enseñado a que las juntas se pueden tomar mientras barres tu casa, es decir, haciendo varias cosas a la vez. Pero ¿Si quieres preparar tu comida pero tu jefe tóxico siempre está al pendiente si te desconectas?

Existen varias soluciones para esto, y la más sencilla es bajando un programa que esté haciendo alguna acción en tu computadora evitando que esta se apague por inactividad.

En este artículo podrás descargar el programa listo para ejecutarse, OJO al ser un ejecutable, probablemente el antivirus lo detecta como malicioso, pero no hay nada de qué preocuparse, el código fuente está disponible por si lo quiere revisar y asegurarse de que es seguro.

Descarga la version del programa, segun tu sistema operativo.

En caso de que seas más curioso y quieras saber como se hacen estos tipos de programa, lo veremos a continuación.

Advertencia: Este ejercicio se hace con el único fin de impartir conocimiento y aprender un poco sobre los alcances de la programación. En ningún momento *guiño* fomentamos dormir en horario laboral *guiño* *guiño*. Así que uselo bajo la propia supervisión de su jefe *guiño*.


Haciendo tu propio programa

Esta pequeña herramienta está hecha enteramente en python, usando pyAutoGui y pySimpleGui y empaquetada usando pyInstaller, así que veremos una breve introducción y ejemplos de de como usar estas librerías donde al final terminaremos con un ejecutable listo para acción.

UI con pySimpleGui

Esto es opcional, si eres de aquellas personas que prefieren usar línea de comandos, este paso te lo puedes saltar, pero poniéndole crema a nuestros tacos, seria bueno crear una pequeña ventanita donde podremos controlar nuestro programa.

PySimpleGUI es Python GUI para humanos, así lo define su página, y con justa razón, ya que en realidad crear una interfaz gráfica en Python es algo relativamente nuevo y no es tan fácil de lograr como con otros lenguajes de programación. Esta librería se basa en tKinter y funciona tanto para Windows, MacOS, linux y también tiene un port para Android, aunque para este último tienes que hacer más configuraciones y requiere de pasos extras. 

Se puede instalar por medio de pip, así que no debería de haber ningún problema:

pip install pysimplegui

Una vez que lo tenemos instalado, podemos crear nuestra ventana con la que podremos controlar nuestra herramienta:

import PySimpleGUI as sg
 
# Función de entrada donde creamos el UI definiéndolo en 'layout'.
# Además, creando un ciclo infinito donde leeremos los eventos lanzados por la ventana.
# En caso de cerrar la ventana, el ciclo se rompe y terminamos la ejecución.
def main():
  sg.theme('Dark')
  layout = [
      [sg.Text('Tu computadora se mantendrá activada mientras esta ventana sigue abierta.')],
      [sg.Text('Tipo de evento:'), sg.Combo(['Mover mouse', 'Volumen arriba/abajo'], default_value='Mover mouse', key='cmbEventTypes', enable_events=True)]
  ]
  window = sg.Window('KeepMeAwake', layout, icon='icn.ico')
   while True:
      event, values = window.read(timeout=100)
      if event == sg.WIN_CLOSED: # Si el usuario cierra la ventana, terminara el programa
          break
  window.close()
 
# Punto de entrada para lanzar nuestro UI
if __name__ == '__main__':
  main()

Y listo, básicamente lo que está haciendo el código anterior es crear el contenido de nuestra ventana  por medio de ‘layout’ y generar una ventana con eso, usando el icono de ‘icn.ico’. Una vez creada la ventana, se crea un loop infinito que cada 100 ms estará leyendo los eventos y en caso de que se cierre la ventana, saldrá de ese ciclo infinito y terminará el programa.

Ejecutar una acción por medio de pyAutoGUI

PyAutoGUI es una librería de python que nos permite ejecutar ciertas acciones en la PC, ya sea presionar una tecla, mover el mouse, tomar capturas de pantalla, etc, de manera automatizada. Al igual que pySimpleGUI se instala por medio de pip.

pip install pyautogui

Independientemente del UI, tenemos que tener la manera de ejecutar la acción que queremos para mantener la PC encendida, ya sea moviendo el ratón o subiendo y bajando el volumen. Esta librería, destinada para crear procesos automatizados en Python, nos ayudará a atacar esta funcionalidad de nuestro programa.

import time, pyautogui, threading
 
# Esta función lanza un evento de tecla presionada.
# En este caso usamos la de subir y bajar volumen.
# Dejando un espacio de 1 seg entre eventos.
def useVolume():
   pyautogui.press('volumedown')
   time.sleep(1)
   pyautogui.press('volumeup')
 
# En esta función se ejecutan movimientos del mouse.
# Mueve el mouse 25 posiciones a la derecha y luego 25 a la izquierda.
# Dejando un espacio de 1 seg entre eventos.
def useMouse():
   pyautogui.move(25,0)
   time.sleep(1)
   pyautogui.move(-25,0)
 
# Ciclo infinito en el que estará ejecutando la acción automatizada.
# Recibe como parámetro el tipo de evento que va a usar
def dontsleep(evnt):
   while True:
       if evnt == 'mouse':
          useMouse()
       else:
           useVolume()
           time.sleep(20)
 
# Punto de entrada desde donde lanzamos nuestro hilo tipo daemon.
# Posteriormente lo conectaremos a nuestro UI para poder controlarlo.
if __name__ == '__main__':
   threading.Thread(target=dontsleep, args=('mouse'), daemon=True).start()

Uniendo el UI con las acciones

Una vez que tenemos las dos partes listas, las juntamos para que controlemos el hilo que corre nuestras acciones automatizadas por medio del UI. Terminaremos con algo como esto:

import time, pyautogui, threading
import PySimpleGUI as sg
 
# Esta bandera nos ayudará a controlar nuestro hilo
runningThread = False
 
def useVolume():
   pyautogui.press('volumedown')
   time.sleep(1)
   pyautogui.press('volumeup')
 
def useMouse():
   pyautogui.move(25,0)
   time.sleep(1)
   pyautogui.move(-25,0)
 
# Agregamos nuestra nueva bandera para poder parar el hilo cuando sea necesario
def dontsleep(evnt):
   global runningThread
   runningThread = True
   while runningThread:
       if evnt == 'mouse':
          useMouse()
       else:
           useVolume()
           time.sleep(20)
 
# Esta función se encarga de parar el hilo y espera hasta que este sea finalizado correctamente
def stopThread(th):
   global runningThread
   if th:
       while(th.is_alive()):
           if runningThread: runningThread = False
 
def main():
   sg.theme('Dark')
   layout = [
       [sg.Text('Tu computadora se mantendrá activada mientras esta ventana sigue abierta.')],
       [sg.Text('Tipo de evento:'), sg.Combo(['Mover mouse', 'Volumen arriba/abajo'], default_value='Mover mouse', key='cmbEventTypes', enable_events=True)]
   ]
   window = sg.Window('KeepMeAwake', layout, icon='icn.ico')
    # Se crea y lanza el nuevo hilo al iniciar el UI
   th = threading.Thread(target=dontsleep, args=('mouse'), daemon=True)
   th.start()
 
   while True:
       event, values = window.read(timeout=100)
       if event == sg.WIN_CLOSED: # Si el usuario cierra la ventana, terminara el programa
          break
       if event == 'cmbEventTypes': # Si cambiamos el tipo de evento, tenemos que detener el hilo actual y lanzar uno nuevo
           stopThread(th)
           if values['cmbEventTypes'] == 'Move Mouse':
               th = threading.Thread(target=dontsleep, args=('mouse'), daemon=True)
           elif values['cmbEventTypes'] == 'Volume Up/Down':
               th = threading.Thread(target=dontsleep, args=('volume'), daemon=True)
           th.start()
   window.close()
 
# Punto de entrada para lanzar nuestro UI
if __name__ == '__main__':
  main()

Y terminamos!

Una vez que cambiemos el tipo de evento, nuestro programa terminará el hilo de la acción y lanza uno nuevo con el evento seleccionado.

Pero ¿por qué agregar varios tipos de evento? Bueno, esto es por el sistema operativo en el que estemos corriendo, se recomienda que para Windows se use el evento de volumen, mientras que para Linux o macOS se use el de mouse.

Así veras tu ventana si la ejecutas en Ubuntu

[Opcional] Creando el ejecutable con pyInstaller

Con los pasos anteriores ya tenemos nuestro programa totalmente funcional, pero si lo quisiéramos distribuir, habría que instalar python y todas las dependencias necesarias para poder ejecutarlo en cualquier PC en el que lo queramos usar. Para mitigar esto, podemos usar pyInstaller que crea un paquete donde incluye todas las dependencias necesarias para ejecutarse, o mejor conocido como standalone.

Al igual que las librerías anteriores, se instala por medio de pip:

pip install pyinstaller

Para usarlo, tenemos que ir al folder donde tenemos nuestro archivo de python y ejecutar lo siguiente:

pyinstaller --clean -i icn.ico --distpath dist\Win --add-data="icn.ico;." -F -w tuPrograma.py

Aquí te explicamos qué hace cada uno de los parámetros:

  • –clean: Vuelve a crear todo desde cero, de esta manera obligamos a que respete los cambios más recientes.
  • -i icn.ico: Crea el ejecutable usando el icono especificado, en este caso está en el mismo folder.
  • –distpath: Ruta donde se creará el archivo ejecutable.
  • –add-data: Archivos y demás información que queramos integrar en nuestro ejecutable, en este ejemplo, solo queremos incluir el icono como ejemplo.
  • -F: Crea un archivo único ejecutable, en lugar de este se puede usar -D para cuando se requiera un folder en lugar de un solo archivo.
  • -w: Elimina la ventana de comandos (depende del sistema operativo en el que se vaya a ejecutar)
  • tuPrograma.py: Es el código del cual va a generar el ejecutable.

OJO, el ejecutable creado solo va a correr en el sistema operativo en el cual se está creando, es decir, si estas usando windows para crear el ejecutable, este solo correrá en windows. Si necesitas que corra en Linux o MacOS, será necesario que ejecutes pyInstaller en el PC adecuado.

Para más detalles e información referente a los parámetros pueden visitar la documentación oficial de pyInstaller.

… Y listo!

Y ya con esto tenemos nuestro propio ejecutable y lo podemos lanzar desde cualquier computadora.

Con esto podemos ver existen librerías sumamente útiles para crear cualquier pequeña herramienta que necesitemos de manera rápida y sencilla.

Aquí les dejamos el código y los scripts de pyinstallers para diferentes sistemas operativos, así como sus ejecutables, por si les quieren echar un ojo.