Как перевести ноутбук в спящий режим при достижении низкого уровня заряда батареи?

Как перевести ноутбук в спящий режим при достижении низкого уровня заряда батареи?

Я использую Ubuntu, но в качестве оконного менеджера вместо среды рабочего стола у меня установлен i3.

Когда заряд батареи достигает 0%, компьютер просто резко выключается, без предупреждения или чего-либо еще.

Есть ли простой скрипт или конфигурация, которые я могу настроить так, чтобы он переходил в спящий режим, скажем, при 4% заряда батареи?

решение1

Вот небольшой скрипт, который проверяет уровень заряда батареи и вызывает специальную команду, здесь pm-hibernate, в случае, если уровень заряда батареи ниже определенного порогового значения.

#!/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

Это очень простой скрипт, но я думаю, вы поняли идею и можете легко адаптировать его под свои нужды. Путь к уровню батареи может быть другим в вашей системе. Немного более портативным, вероятно, было бы использовать что-то вроде acpi | cut -f2 -d,для получения уровня батареи. Этот скрипт можно запланировать с помощью cron на запуск каждую минуту. Отредактируйте ваш crontab с помощью crontab -eи добавьте скрипт:

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

Другим решением будет установка среды рабочего стола, например Gnome или Xfce (и изменение вашего оконного менеджера на i3). Обе упомянутые среды рабочего стола имеют демоны управления питанием, которые отвечают за выключение компьютера. Но я предполагаю, что вы намеренно не используете их и ищете более минималистичное решение.

решение2

Вместо того, чтобы взламывать собственные скрипты, и если вы используете Ubuntu, как предполагает тег, вы можете просто установить пакет upower. Он должен быть доступен во всех производных Debian, включая Ubuntu. По умолчанию он поставляется с конфигурацией, в /etc/UPower/UPower.confкоторой активируется гибридный спящий режим, как только уровень заряда батареи достигает критических значений. По умолчанию критический уровень составляет 2%.

Для пользователей других дистрибутивов соответствующие записи /etc/UPower/UPower.conf:

PercentageAction=2
CriticalPowerAction=HybridSleep

Вы также можете использовать TimeActionвместе с UsePercentageForPolicy=false, чтобы действие было выполнено только тогда, когда останется только указанное время:

TimeAction=120

Допустимые значения для CriticalPowerAction, PowerOffи Hibernate. HybridSleepЕсли HybridSleep установлен, но недоступен, будет использоваться режим гибернации. Если Hibernate установлен, но недоступен, будет использоваться режим PowerOff.

Преимущество HybridSleep в том, что в дополнение к записи памяти в область подкачки, он затем приостанавливает работу системы. Приостановка все равно будет потреблять некоторое количество батареи, но если вы вернетесь до того, как батарея разрядится, вы сможете гораздо быстрее возобновить работу из приостановленной системы, чем из спящей. В случае, если батарея разрядится до того, как вы вернетесь к розетке, вы сможете возобновить работу системы из спящего режима, как только у вас снова появится питание.

решение3

Начиная с Debian ≥ 10 (и сравнительно новых систем Linux) вы можете просто создать файл, /etc/cron.d/check-batteryсодержащий:

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

Это приведет к приостановке работы системы, когда уровень заряда батареи достигнет 30%.

Конечно, вы можете свободно заменить финал suspendна hybrid-sleep, hibernate, poweroffили на любой другой вариант, который вам больше подходит.

Никаких внешних инструментов не требуется, даже acpiпакета. Это основано на идее ответа Матии Налис, но скорректировано на 2023 год.

решение4

Реализовать это можно разными способами, поскольку существует множество различных схем управления питанием в зависимости от того, что у вас установлено.

Этот простой вариант работает у меня на минималистичном Debian Jessie без какой-либо среды рабочего стола, только с небольшим и быстрым оконным менеджером icewm. (Он урезан, потому что в противном случае он был бы слишком медленным, и таким образом он превосходит GNOME на гораздо лучшем оборудовании)

В частности, у меня УСТАНОВЛЕНЫ следующие пакеты: acpi acpi-fakekey acpi-support acpi-support-base acpid pm-utils но НЕ имеют НИЧЕГО из нижеперечисленного (после их очистки): gnome* kde* systemd* uswsusp upower laptop-mode-tools спящий режим policykit-1

Поэтому я просто вставил это /etc/cron.d/battery_low_check(всё в одну строку, разделенную для удобства чтения):

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

Он быстрый, потребляет мало ресурсов и не зависит от других демонов (на самом деле, он будет проигнорирован, если они активны — /usr/share/acpi-support/policy-funcsподробности см. здесь).

Что оно делает:каждые 5 минут ( */5- вы можете изменить на каждую минуту, просто нажав , *если вам нужно чаще проверять батарею) он будет опрашивать состояние батареи ("acpi --батарея") и выполнить команду xargs -riтолько после этого, если аккумулятор находится в состоянии "Разряжается" (то есть вы не подключены к сети переменного тока) и состояние аккумулятора меньше 10%("целое число ($2) < 10" - не стесняйтесь настраивать его под свои нужды)

acpi_fakekey 205по умолчанию отправит KEY_SUSPENDсобытие ACPI (например, вы нажали клавишу на ноутбуке, запрашивая переход в режим ожидания), которое затем выполнит то, что оно обычно делает для вас (настроено в /etc/default/acpi-support) - в моем случае это переход в спящий режим на диск.

Конечно , вместо acpi_fakekey 205этого вы можете использовать другие команды: например, hibernate(из пакета hibernate) s2diskили s2mem(из пакета uswsusp), pm-suspend-hybrid(из пакета pm-utils) и т. д.

Кстати, магические ключевые цифры, такие какKEY_SUSPEND=205выше определены в /usr/share/acpi-support/key-constants(другой интересный, вероятно,КЛЮЧ_СОН=142)

Связанный контент