
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 -e
e 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.conf
qual 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.conf
são:
PercentageAction=2
CriticalPowerAction=HybridSleep
Você também pode usar TimeAction
junto com UsePercentageForPolicy=false
para permitir que a ação seja executada quando resta apenas o tempo especificado:
TimeAction=120
Os valores válidos para CriticalPowerAction
são PowerOff
, Hibernate
e 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-battery
que 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 suspend
por hybrid-sleep
, hibernate
ou poweroff
o que melhor se adequar às suas necessidades.
Nenhuma ferramenta externa é necessária, nem mesmo o acpi
pacote. 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-funcs
detalhes).
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 -ri
somente 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 205
por padrão, enviará KEY_SUSPEND
um 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) s2disk
ou 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)