Привет всем,
Достаточно интересная задачка пришла, в которой интересно было покапаться. Имеем физический сервер с ubuntu на борту, и подключенным питанием в бесперебойник.
Нам требуется настроить операционку, на отправку системы в suspend mode. И задача упрощается, так как UPS за собой имеет usb-интерфейс, который мы подключим к серверу.
(схема подключения)
Для решения этой задачи определил для себя два способа:
- Интересный способ, это написания собственного скрипта с добавлением в него уведомления;
- Нативный способ, это перенастройка окружения за счет встроенных функций оконного менеджера.
Рассмотрим оба варианта реализации.
Написание собственного скрипта
В 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 минут. И запуститься при его восстановлении.
Тоже самое можно выполнить и из под окружения: