Como faço para que meu laptop hiberne quando ele atinge um limite de bateria fraca?

Como faço para que meu laptop hiberne quando ele atinge um limite de bateria fraca?

Estou usando o Ubuntu, mas tenho o i3 como gerenciador de janelas em vez de um ambiente de desktop.

Quando minha bateria chega a 0%, o computador desliga abruptamente, sem aviso nem nada.

Existe um script ou configuração simples que eu possa definir para que ele hiberne com, digamos, 4% da bateria?

Responder1

Aqui está um pequeno script que verifica o nível da bateria e chama um comando personalizado, aqui pm-hibernate, caso o nível da bateria esteja abaixo de um determinado limite.

#!/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 required because the script is invoked by cron. Dbus information
# is stored 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
  source ~/.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

É um script muito simples, mas acho que você entendeu e pode adaptá-lo facilmente às suas necessidades. O caminho para o nível da bateria pode ser diferente no seu sistema. Um pouco mais portátil provavelmente seria usar algo como acpi | cut -f2 -d,obter o nível da bateria. Este script pode ser agendado pelo cron para ser executado a cada minuto. Edite seu crontab crontab -ee adicione o script:

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

Outra solução seria instalar um ambiente de desktop como Gnome ou Xfce (e mudar seu gerenciador de janelas para i3). Ambos os ambientes destop mencionados apresentam daemons de gerenciamento de energia que cuidam de desligar o computador. Mas presumo que você deliberadamente não os usa e está procurando uma solução mais minimalista.

Responder2

Em vez de hackear seus próprios scripts e se estiver usando o Ubuntu como a tag sugere, você pode simplesmente instalar o pacote upower. Deve estar disponível em todos os derivados do Debian, incluindo o Ubuntu. Por padrão ele vem com uma configuração na /etc/UPower/UPower.confqual ativa o sono híbrido quando o nível da bateria atinge valores críticos. O padrão para o nível crítico é 2%.

Para usuários de outras distribuições, as entradas relevantes /etc/UPower/UPower.confsão:

PercentageAction=2
CriticalPowerAction=HybridSleep

Você também pode usar TimeActionjunto com UsePercentageForPolicy=falsepara permitir que a ação seja executada quando resta apenas o tempo especificado:

TimeAction=120

Os valores válidos para CriticalPowerActionsão PowerOff, Hibernatee HybridSleep. Se HybridSleep estiver definido, mas não disponível, o Hibernate será usado. Se o Hibernate estiver definido, mas não disponível, PowerOff será usado.

A vantagem do HybridSleep é que, além de gravar memória na sua área de troca, ele suspende o sistema. A suspensão ainda consumirá um pouco de bateria, mas se você voltar antes que a bateria acabe, poderá retomar muito mais rapidamente de um sistema suspenso do que de um sistema hibernado. Caso a bateria acabe antes de você voltar à tomada, você pode retomar o sistema da hibernação assim que tiver energia novamente.

Responder3

A partir do Debian ≥ 10 (e sistemas Linux comparativamente recentes), você pode simplesmente criar um arquivo /etc/cron.d/check-batteryque contenha:

* * * * * root [ "$(cat /sys/class/power_supply/BAT0/status)" != Discharging -o "$(cat /sys/class/power_supply/BAT0/capacity)" -gt 30 ] || systemctl suspend

Isso suspenderá seu sistema sempre que o nível da bateria atingir 30%.

Claro, sinta-se à vontade para substituir o final suspendpor hybrid-sleep, hibernateou poweroffo que melhor se adequar às suas necessidades.

Nenhuma ferramenta externa é necessária, nem mesmo o acpipacote. Baseia-se na ideia da resposta de Matija Nalis, mas ajustada para o ano de 2023.

Responder4

Há muitas maneiras de implementá-lo, pois existem muitos esquemas diferentes de gerenciamento de energia implementados dependendo do que você instalou.

Este simples funciona para mim no Debian Jessie minimalista, sem qualquer ambiente de desktop, apenas com o pequeno e rápido gerenciador de janelas icewm. (Ele é reduzido porque é muito lento e, dessa forma, supera o GNOME em hardware muito melhor)

Especificamente, eu instalei os seguintes pacotes: acpi acpi-fakekey acpi-support acpi-support-base acpid pm-utils mas não tem NENHUMA das seguintes opções (depois de eliminá-las): gnome* kde* systemd* uswsusp upower laptop-mode-tools hibernate policykit-1

Então acabei de colocar isso /etc/cron.d/battery_low_check(tudo em uma linha, dividido para facilitar a leitura):

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

É rápido, consome poucos recursos e não depende de outros demônios (na verdade, será ignorado se eles estiverem ativos - veja /usr/share/acpi-support/policy-funcsdetalhes).

O que faz:a cada 5 minutos ( */5- você pode mudar para cada minuto apenas usando *se precisar verificar a bateria com mais frequência) ele pesquisará o status da bateria ("acpi --bateria") e execute o comando xargs -risomente se a bateria estiver "Descarregando" (ou seja, você não estiver conectado à CA) e o status da bateria for menor que 10%("interno ($2) <10" - sinta-se à vontade para ajustá-lo às suas necessidades)

acpi_fakekey 205por padrão, enviará KEY_SUSPENDum evento ACPI (como se você tivesse pressionado uma tecla no laptop solicitando a suspensão), que fará o que normalmente faz por você (configurado em /etc/default/acpi-support) - para mim, ele hiberna no disco.

Você pode usar outro comando em vez de, acpi_fakekey 205é claro: como hibernate(do pacote hibernate) s2diskou s2mem(do pacote uswsusp), pm-suspend-hybrid(do pacote pm-utils) etc.

Aliás, números-chave mágicos comoKEY_SUSPEND=205acima são definidos em /usr/share/acpi-support/key-constants(outro interessante é provavelmenteKEY_SLEEP=142)

informação relacionada