Привет всем,

Достаточно интересная задачка пришла, в которой интересно было покапаться. Имеем физический сервер с ubuntu на борту, и подключенным питанием в бесперебойник.

Нам требуется настроить операционку, на отправку системы в suspend mode. И задача упрощается, так как UPS за собой имеет usb-интерфейс, который мы подключим к серверу.

ubuntu-suspend-schemes.png (схема подключения)

Для решения этой задачи определил для себя два способа:

  • Интересный способ, это написания собственного скрипта с добавлением в него уведомления;
  • Нативный способ, это перенастройка окружения за счет встроенных функций оконного менеджера.

Рассмотрим оба варианта реализации.

Написание собственного скрипта

В ubuntu, да и не только, информацию относительно устройств питания можно вытащить при помощи утилиты upower.

Для вывода всех объектов можно воспользоваться командой:

tvset@Sysadmin-TVSER:~$ upower -e
--
/org/freedesktop/UPower/devices/ups_hiddev0
/org/freedesktop/UPower/devices/DisplayDevice

В этом выводе нам интересен объект - ups_hiddev0, предполагаемый наш подключенный UPS. Для вывода информации по объекту запустить команду upower с ключом -i/--show-info:

tvset@Sysadmin-TVSER:~$ upower -i /org/freedesktop/UPower/devices/ups_hiddev0
---
  native-path:          /sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2/1-1.2:1.0/usbmisc/hiddev0
  vendor:               American Power Conversion
  model:                Back-UPS XS 650CI
  serial:               3B1435X02884  
  power supply:         yes
  updated:              иш 10 сен 2022 02:45:29 (22 seconds ago)
  has history:          yes
  has statistics:       yes
  ups
    present:             yes
    state:               fully-charged
    warning-level:       none
    time to empty:       14,4 minutes
    percentage:          100%
    icon-name:          'battery-full-charged-symbolic'

В информации по объекту содержатся данные, описание и модель устройства, состояние и его статистика. В блоке ups, описывается статус и процентаж батареи. Также обозначается примерное время работы от батареи.

Для демонстрации, я отключил основное питание от ups. Подолжал пару минут и сново вывел информацию по батарейке.

tvset@Sysadmin-TVSER:~$ upower -i /org/freedesktop/UPower/devices/ups_hiddev0
---
  native-path:          /sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2/1-1.2:1.0/usbmisc/hiddev0
  vendor:               American Power Conversion
  model:                Back-UPS XS 650CI
  serial:               3B1435X02884  
  power supply:         yes
  updated:              иш 10 сен 2022 03:57:59 (20 seconds ago)
  has history:          yes
  has statistics:       yes
  ups
    present:             yes
    state:               discharging
    warning-level:       discharging
    time to empty:       55,0 minutes
    percentage:          97%
    icon-name:          'battery-full-symbolic'

Как можно понять из вывода, сейчас статус батареи - discharging, и емкость батареи также уменьшилась.

Зацепимся за эти две метрики, и напишем скриптец, который будет отправлять систему suspend.

#!/bin/bash

TIMESTAMP=$(date +"%Y-%m-%d %H:%M")
LOG_PATH="/var/log/ups-checker.log"
CAPACITY_LIMIT=50
UPS_PATH=$(upower -e | grep -i ups)
UPS_CAPACITY=$(upower -i $UPS_PATH | grep -i percentage | cut -d':' -f2 | sed 's/[^0-9]*//g')
UPS_STATUS=$(upower -i $UPS_PATH | grep -i state | cut -d':' -f2 | sed 's/\s*//g')


if [ $UPS_STATUS = "discharging" ]; then
    MESSAGE="$TIMESTAMP: Power supply problems, on $(hostname). Battery percentage - $UPS_CAPACITY% "
    echo $MESSAGE >>  $LOG_PATH
    if [[ $UPS_CAPACITY -lt $CAPACITY_LIMIT ]]; then
        MESSAGE="$TIMESTAMP: Battery percentage is $UPS_CAPACITY. System halt.."
        /usr/bin/systemctl suspend
        exit 99
    fi
fi

В начале объявляются переменные:

  • TIMESTAMP - в значении текущая дата и время. Эта переменная нужна для отображения события в логфайле,
  • LOG_PATH - тут указывается путь до лог-файла,
  • CAPACITY_LIMIT - указывается лимит, при достижения которого мы хотим отключать систему,
  • UPS_PATH - в значении это переменной определяется путь до объекта UPS,
  • UPS_CAPACITY - эта переменная содержит процент заряда батареи, который вырезается из вывода команды upower,
  • UPS_STATUS - ну и тут в значение попадает, результат команды upower. Из вывода вырезается статус батарейки

Далее в скрипте идет конструкция условного оператора, в условии которого проверяется статус батарейки. И если условие срабатывает, то пишется сообшение в лог. Затем внутри проверяется вложенное условие, которое выполнится если текущий процентаж батареи ниже лимита (Ниже 50% в нашем случаи). Будет отправлено соответствующее сообшение в лог, и система отключится.

Теперь остается только добавить скрипт в задание cron и можно тестировать. Закидываем скриптец к исполняемым файлам:

tvset@Sysadmin-TVSER:~$ sudo mv Documents/ups_checker.sh /usr/local/bin/

Даем право исполнения скрипта:

tvset@Sysadmin-TVSER:~$ sudo chmod +x /usr/local/bin/ups_checker.sh

Ну и создаем задание в cron на выполнение, каждые 3 минуты:

tvset@Sysadmin-TVSER:~$ sudo vim /etc/crontab
---
# UPS Checker
*/3 * * * *     root    /usr/bin/bash -c /usr/local/bin/ups_checker.sh

При желании можно добавить нотификацию в telegram или на почту. Но имеет ли смысл это, когда сети нету и не всегда есть доступ к интернет при выключенном электричестве.

Нативный способ

Эту же задачу можно решить более нативным методом за счет оконного менеджера gnome, с использованием его настройки в gnome-control-central. Путем использовании пары команд.

Для начала выставим таймаут для системы, при работе системы от батарейки:

tvset@Sysadmin-TVSER:~$ gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-battery-timeout 300

В данном случаи, мы выставляем таймаут на 5 мин.

Теперь установим тип действия, при работе от батарейки. Имеется ввиду при работе от батареи, когда достигнет таймаут установленный выше, произойдет выключение или приостановка (suspend) системы. Для установки действия, воспользуемся командой:

tvset@Sysadmin-TVSER:~$ gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-battery-type suspend

На этом всем, можно проверить работу. Система уйдет в suspend, при отсутствии питания на UPS свыше 5 минут. И запуститься при его восстановлении.

Тоже самое можно выполнить и из под окружения: ubuntu-suspend-gnome.png