¿Cómo hago que mi computadora portátil duerma cuando alcanza un umbral de batería baja?

Estoy usando Ubuntu, pero tengo i3 como mi administrador de windows.

En i3, cuando mi batería alcanza el 0%, la computadora se apagará abruptamente, sin advertencia ni nada.

¿Existe un script o configuration simple que pueda configurar para que duerma en, digamos 4% de batería?

Aquí hay un pequeño script que verifica el nivel de la batería y llama a un command personalizado, aquí pm-hibernate , en caso de que el nivel de la batería esté por debajo de un cierto umbral.

 #!/bin/sh ########################################################################### # # Usage: system-low-battery # # Checks if the battery level is low. If “low_threshold” is exceeded # a system notification is displayed, if “critical_threshold” is exceeded # a popup window is displayed as well. If “OK” is pressed, the system # shuts down after “timeout” seconds. If “Cancel” is pressed the script # does nothing. # # This script is supposed to be called from a cron job. # ########################################################################### # This is requinetworking because the script is invoked by cron. Dbus information # is stonetworking in a file by the following script when a user logs in. Connect # it to your autostart mechanism of choice. # # #!/bin/sh # touch $HOME/.dbus/Xdbus # chmod 600 $HOME/.dbus/Xdbus # env | grep DBUS_SESSION_BUS_ADDRESS > $HOME/.dbus/Xdbus # echo 'export DBUS_SESSION_BUS_ADDRESS' >> $HOME/.dbus/Xdbus # exit 0 # if [ -r ~/.dbus/Xdbus ]; then . ~/.dbus/Xdbus fi low_threshold=10 critical_threshold=4 timeout=59 shutdown_cmd='/usr/sbin/pm-hibernate' level=$(cat /sys/devices/platform/smapi/BAT0/remaining_percent) state=$(cat /sys/devices/platform/smapi/BAT0/state) if [ x"$state" != x'discharging' ]; then exit 0 fi do_shutdown() { sleep $timeout && kill $zenity_pid 2>/dev/null if [ x"$state" != x'discharging' ]; then exit 0 else $shutdown_cmd fi } if [ "$level" -gt $critical_threshold ] && [ "$level" -lt $low_threshold ]; then notify-send "Battery level is low: $level%" fi if [ "$level" -lt $critical_threshold ]; then notify-send -u critical -t 20000 "Battery level is low: $level%" \ 'The system is going to shut down in 1 minute.' DISPLAY=:0 zenity --question --ok-label 'OK' --cancel-label 'Cancel' \ --text "Battery level is low: $level%.\n\n The system is going to shut down in 1 minute." & zenity_pid=$! do_shutdown & shutdown_pid=$! trap 'kill $shutdown_pid' 1 if ! wait $zenity_pid; then kill $shutdown_pid 2>/dev/null fi fi exit 0 

Es un guión muy simple, pero creo que entiendes la idea y puedes adaptarla fácilmente a tus necesidades. El path al nivel de la batería puede ser diferente en su sistema. Un poco más portátil probablemente sería usar algo como acpi | cut -f2 -d, acpi | cut -f2 -d, para get el nivel de la batería. Esta secuencia de commands se puede progtwigr por cron para que se ejecute cada minuto. Edite su crontab con crontab -e y agregue el script:

 */1 * * * * /home/me/usr/bin/low-battery-shutdown 

Otra solución sería instalar un entorno de escritorio como Gnome o Xfce (y cambiar su administrador de windows a i3). Ambos entornos destop mencionados countn con daemons de administración de energía que se encargan de apagar la computadora. Pero supongo que deliberadamente no los usa y busca una solución más minimalist.

La respuesta actualmente aceptada es excelente, pero un poco obsoleta para Ubuntu 16.04:

  • Los commands para get el estado de la batería han cambiado.
  • Las variables de entorno requeridas para notify-send al trabajo han cambiado .
  • El script dado allí ya no funciona desde el cron del usuario, ya que hibernate requiere root.
  • systemctl hibernate es preferible a pm-hibernate .

Entonces, aquí está el script que uso:

 #!/usr/bin/env bash # Notifies the user if the battery is low. # Executes some command (like hibernate) on critical battery. # This script is supposed to be called from a cron job. # If you change this script's name/path, don't forget to update it in crontab !! level=$(cat /sys/class/power_supply/BAT1/capacity) status=$(cat /sys/class/power_supply/BAT1/status) # Exit if not discharging if [ "${status}" != "Discharging" ]; then exit 0 fi # Source the environment variables requinetworking for notify-send to work. . /home/anmol/.env_vars low_notif_percentage=20 critical_notif_percentage=15 critical_action_percentage=10 if [ "${level}" -le ${critical_action_percentage} ]; then # sudo is requinetworking when running from cron sudo systemctl hibernate exit 0 fi if [ "${level}" -le ${critical_notif_percentage} ]; then notify-send -i '/usr/share/icons/gnome/256x256/status/battery-caution.png' "Battery critical: ${level}%" exit 0 fi if [ "${level}" -le ${low_notif_percentage} ]; then notify-send -i '/usr/share/icons/gnome/256x256/status/battery-low.png' "Battery low: $level%" exit 0 fi 

Las variables de entorno requeridas para notify-send al trabajo se crean utilizando este script :

 #!/usr/bin/env bash # Create a new file containing the values of the environment variables # requinetworking for cron scripts to work. # This script is supposed to be scheduled to run at startup. env_vars_path="$HOME/.env_vars" rm -f "${env_vars_path}" touch "${env_vars_path}" chmod 600 "${env_vars_path}" # Array of the environment variables. env_vars=("DBUS_SESSION_BUS_ADDRESS" "XAUTHORITY" "DISPLAY") for env_var in "${env_vars[@]}" do echo "$env_var" env | grep "${env_var}" >> "${env_vars_path}"; echo "export ${env_var}" >> "${env_vars_path}"; done 

Este file necesita ejecutarse al inicio (se puede hacer usando cualquier método de su elección, yo uso las aplicaciones de inicio integradas de Ubuntu).

Nota: sudo systemctl hibernate podría no funcionar desde cron. Sigue esto para resolverlo.

En lugar de piratear tus propios scripts y si estás utilizando Ubuntu como sugiere la label, simplemente puedes instalar el package upower. Debería estar disponible en todos los derivados de Debian, incluido Ubuntu. Por defecto viene con una configuration en /etc/UPower/UPower.conf que activa la suspensión híbrida una vez que el nivel de la batería alcanza valores críticos. El valor pnetworkingeterminado para el nivel crítico es 2%.

Para los usuarios de otras distribuciones, las inputs relevantes para /etc/UPower/UPower.conf son:

 PercentageAction=2 CriticalPowerAction=HybridSleep 

También puede utilizar TimeAction junto con UsePercentageForPolicy=false para permitir que la acción se lleve a cabo una vez que solo quede el time especificado:

 TimeAction=120 

Los valores válidos para CriticalPowerAction son PowerOff , Hibernate e HybridSleep . Si HybridSleep está configurado pero no está disponible, se usará Hibernate. Si Hibernate está configurado pero no está disponible, se usará PowerOff.

La ventaja de HybridSleep es que, además de escribir memory en su área de intercambio, suspende el sistema. Suspender aún consumirá algo de batería, pero si regresa antes de que se agote la batería, puede reanudar mucho más rápidamente desde un sistema suspendido que desde uno en hibernación. En caso de que la batería se agote antes de volver a la toma de stream, puede reanudar el sistema de la hibernación una vez que tenga energía nuevamente.

Hay muchas maneras en que se puede implementar, ya que hay muchos esquemas de administración de energía implementados dependiendo de lo que haya instalado.

Este sencillo funciona para mí en Debian Jessie minimalist sin ningún entorno de escritorio, solo con el administrador de windows icewm pequeño y rápido. (Se recorta porque es demasiado lento de lo contrario, y de esta manera supera a GNOME en hardware mucho mejor)

Específicamente, SÍ tengo instalados los siguientes packages: acpi acpi-fakekey acpi-support acpi-support-base acpid pm-utils pero no tienen NINGUNO de los siguientes (habiéndolos purgado): gnome * kde * systemd * uswsusp upower laptop-mode-tools hibernate policykit-1

Así que puse esto en /etc/cron.d/battery_low_check (todo en una línea, split para legibilidad):

 */5 * * * * root acpi --battery | awk -F, '/Discharging/ { if (int($2) < 10) print }' | xargs -ri acpi_fakekey 205 

Es rápido, utiliza pocos resources y no depende de otros deamons (de hecho, se ignorará si están activos; consulte /usr/share/acpi-support/policy-funcs para get más información).

Qué hace: cada 5 minutos ( */5 – puede cambiar a cada minuto usando solo * si lo necesita para verificar la batería más a menudo) sondeará el estado de la batería (" acpi –battery ") y ejecutará el command después de xargs -ri solo si la batería está "Descargando" (es decir, no está conectado a la CA) y el estado de la batería es inferior al 10% (" int ($ 2) <10 "), siéntase libre de ajustarlo a sus necesidades)

acpi_fakekey 205 enviará por defecto el evento KEY_SUSPEND ACPI (como que presionó una tecla en el portátil solicitando suspender), que luego hará lo que normalmente hace por usted (configurado en /etc/default/acpi-support ) – para mí hiberna en el disco .

Podría usar otro command en lugar de acpi_fakekey 205 por supuesto: como hibernate (del package hibernate), s2disk o s2mem (del package uswsusp), pm-suspend-hybrid suspend pm-suspend-hybrid (del package pm-utils), etc.

Por cierto, los numbers key mágicos como KEY_SUSPEND = 205 arriba se definen en /usr/share/acpi-support/key-constants (otro interesante es probablemente KEY_SLEEP = 142 )

Me gusta esta solución, que está inspirada en parte por otras respuestas: https://github.com/jerrinfrncs/batterynotif , es decir, el script batterynotif(uname).sh .

Vea el script aquí: https://github.com/jerrinfrncs/batterynotif/blob/master/batterynotif%28uname%29.sh

Para mi propio uso, he cambiado la secuencia de commands para ingresar hybrid-sleep en lugar de apagar, usando el command systemctl hybrid-sleep . (Se necesita espacio de intercambio con esta opción).