acpid (Русский)
Состояние перевода: На этой странице представлен перевод статьи acpid. Дата последней синхронизации: 11 января 2022. Вы можете помочь синхронизировать перевод, если в английской версии произошли изменения.
acpid2 — это гибкий и расширяемый демон для доставки событий ACPI. Когда происходит событие, демон запускает программы для его обработки. Эти события запускаются определёнными действиями, такими как:
- Нажатие специальных кнопок, включая кнопки выключения и сна
- Закрытие крышки ноутбука
- Подключение или отключение внешнего питания ноутбука
- Подключение или отключение наушников и т.д.
Примечание: Окружения рабочего стола, такие как GNOME, менеджер входа systemd и демоны обработки дополнительных клавиш могут реализовывать собственные схемы обработки событий, независимые от acpid. Одновременный запуск нескольких систем может приводить к неожиданному поведению, такому как двойному уходу в ждущий режим после нажатия кнопки сна. Вы должны помнить об этом и включать только желаемые обработчики.
Установка
Настройка
acpid поставляется с рядом предопределенных действий для событий, например для того, что должно произойти при нажатии кнопки питания. По умолчанию эти действия определены в файле /etc/acpi/handler.sh , который выполняется после возникновения любого ACPI-события (как указано в /etc/acpi/events/anything ).
Ниже приводится краткий пример одного из таких действий. В этом случае при нажатии кнопки сна acpid запускает команду echo -n mem >/sys/power/state , которая должна увести компьютер в ждущий режим:
button/sleep) case "$2" in SLPB) echo -n mem >/sys/power/state ;; *) logger "ACPI action undefined: $2" ;; esac ;;
К сожалению, не все компьютеры называют ACPI-события одинаково. Например, кнопка сна на одних компьютерах обозначается как SLPB, а на других как SBTN.
Чтобы узнать, как определяются ваши кнопки или Fn сочетания клавиш, запустите просмотр журнала:
# journalctl -f
и затем понажимайте интересующие вас кнопки. В журнале должны появиться подобные записи:
logger: ACPI action undefined: PBTN logger: ACPI action undefined: SBTN
Если это не работает, запустите:
# acpi_listen
$ netcat -U /var/run/acpid.socket
Затем нажмите кнопку питания, и вы увидите что-то такое:
button/power PBTN 00000000 00000b31
Вывод команды acpi_listen отправляется /etc/acpi/handler.sh в виде параметров $1, $2, $3 и $4. Например:
$1 button/power $2 PBTN $3 00000000 $4 00000b31
Как вы могли заметить, в данном примере кнопка сна определилась как SBTN, а не как SLPB, прописанный по умолчанию в файле /etc/acpi/handler.sh . Чтобы кнопка сна работала, может понадобиться исправить SLPB) на SBTN).
Базируясь на этой информации, вы можете легко изменить файл /etc/acpi/handler.sh для выполнения различных команд в зависимости от запускаемых событий. Смотрите раздел #Советы и рекомендации ниже, чтобы узнать о других часто используемых командах.
Альтернативная настройка
По умолчанию все события ACPI проходят через скрипт /etc/acpi/handler.sh . Это прописано в правиле /etc/acpi/events/anything :
# Pass all events to our one handler script event=.* action=/etc/acpi/handler.sh %e
Хотя это нормально работает как есть, некоторые пользователи предпочитают разделить правила и действия на отдельные файлы. Следующий пример показывает, как можно как можно создать отдельный файл событий и соответствующий ему скрипт.
Будучи суперпользователем, создайте следующие файлы:
/etc/acpi/events/sleep-button
event=button sleep.* action=/etc/acpi/actions/sleep-button.sh %e
/etc/acpi/actions/sleep-button.sh
#!/bin/sh case "$3" in SLPB) echo -n mem >/sys/power/state ;; *) logger "ACPI action undefined: $3" ;; esac
Сделайте скрипт исполняемым и перезагрузите службу acpid.service , чтобы она прочла и применила изменения в этих файлах.
Советы и рекомендации
Примечание: Некоторые из описанных здесь действий, такие как переключение Wi-Fi и управление подсветкой, уже могут обрабатываться непосредственно драйвером. Сверьтесь с документацией соответствующих модулей ядра.
Примеры событий
Ниже приведены примеры событий, которые можно использовать в скрипте /etc/acpi/handler.sh . Их следует адаптировать под ваше конкретное окружение, например изменить названия переменных, интерпретируемых acpi_listen .
Для изменения яркости экрана ноутбука при подключении или отключении внешнего питания (числа может понадобиться поправить в соответствии с /sys/class/backlight/acpi_video0/max_brightness ):
ac_adapter) case "$2" in AC*|AD*) case "$4" in 00000000) echo -n 50 > /sys/class/backlight/acpi_video0/brightness ;; 00000001) echo -n 100 > /sys/class/backlight/acpi_video0/brightness ;; esac
Включение управления громкостью
Найдите acpi идентификаторы кнопок громкости (смотрите выше) и подставьте их в файлы ниже.
/etc/acpi/events/vol-d
event=button/volumedown action=amixer set Master 5-
/etc/acpi/events/vol-m
event=button/mute action=amixer set Master toggle
/etc/acpi/events/vol-u
event=button/volumeup action=amixer set Master 5+
Примечание: Эти команды могут не работать как задумано с PulseAudio. [1] Для полноценной работы запускайте команды от имени текущего пользователя, указав переменную окружения XDG_RUNTIME_DIR , например sudo -u пользователь XDG_RUNTIME_DIR=/run/user/1000 pactl .
Совет: Отключите или привяжите кнопки громкости в Xorg, чтобы предотвратить конфликты с другими приложениями. Смотрите xmodmap (Русский) для подробностей.
Включение управления подсветкой
Можно настроить управление яркостью экрана аналогичным образом. Напишите примерно такой скрипт-обработчик:
/etc/acpi/handlers/bl
#!/bin/sh bl_dev=/sys/class/backlight/acpi_video0 step=1 case $1 in -) echo $(($(< $bl_dev/brightness) - $step)) >$bl_dev/brightness;; +) echo $(($(< $bl_dev/brightness) + $step)) >$bl_dev/brightness;; esac
и подключите его к ACPI событиям:
/etc/acpi/events/bl_d
event=video/brightnessdown action=/etc/acpi/handlers/bl -
/etc/acpi/events/bl_u
event=video/brightnessup action=/etc/acpi/handlers/bl +
Переключение Wi-Fi
Вы также можете создать простой переключатель питания Wi-Fi адаптера нажатием кнопки WLAN. Пример события:
/etc/acpi/events/wlan
event=button/wlan action=/etc/acpi/handlers/wlan
и его обработчик:
/etc/acpi/handlers/wlan
#!/bin/sh rf=/sys/class/rfkill/rfkill0 case $(< $rf/state) in 0) echo 1 >$rf/state;; 1) echo 0 >$rf/state;; esac
Получение имени пользователя текущего дисплея
Чтобы запускать команды, зависимые от Xorg, требуется определить X-дисплей и файл MIT magic cookie (через XAUTHORITY). Последний — это учётные данные безопасности, предстоавляющие доступ к X-серверу, экрану и устройствам ввода.
Смотрите [3] как пример функции при использовании xinitrc.
- Если подсветка экрана не отключается при закрытии крышни ноутбука, можно попробовать сделать это вручную путём запуска getXuser xset dpms force off и getXuser xset dpms force on при событиях открытия и закрытия крышки соответственно. Если дисплей погаснет, но подсветка останется включенной, используйте вместо этого vbetool с командами vbetool dpms off и vbetool dpms on . Смотрите также XScreenSaver#Configuration.
- При использовании who или w убедитесь, что /run/utmp создаётся при загрузке системы. Подробнее смотрите utmp(5) .
Подключение к сокету acpid
В дополнение к файлам правил acpid принимает соединения по UNIX-сокету, по умолчанию /var/run/acpid.socket . Пользовательские приложения могут подключаться к нему.
#!/bin/bash coproc acpi_listen trap 'kill $COPROC_PID' EXIT while read -u "$" -a event; do handler.sh "$" done
Где handler.sh может быть скриптом, подобным /etc/acpi/handler.sh .
Смотрите также
- домашняя страница acpid
- Gentoo:ACPI#Configuration
ACPI
ACPI (Advanced Configuration and Power Interface) — усовершенствованный интерфейс конфигурации и управления питанием, его задача — обеспечить взаимодействие между операционной системой, аппаратным обеспечением и BIOS материнской платы. Особо нужен в ноутбуках, без ACPI, например, ОС не может определить заряд батареи, девайс неправильно реагирует на нажатие кнопки «Power» и быстро разряжается.
Как взаимодействовать с прошивкой BIOS операционной системе объясняет таблица DSDT (хотя вместо неё это могут быть и другие таблицы типа SSDT или SRAT). Эта таблица запросто может быть некорректной, как некорректным может быть и сама прошивка BIOS. В результате от ACPI может быть больше проблем, чем пользы, в таком случае его проще отключить. Для этого нужно добавить «acpi=off» к опциям загрузки ядра (см. grub)
Управление оборудованием
Для установки действия при закрытии крышки — изменяем скрипт
/etc/acpi/actions/lm_lid.sh
Для установки действия при нажатии кнопки питания — изменяем скрипт
/etc/acpi/powerbtn.sh
Тонкая настройка ACPI на примере Thinkpad X220
За прошедшие пару месяцев мне довольно часто приходилось вступать в дискуссии о всевозможных портативных компьютерах: ломать копья в спорах какой производитель лучше и почему, обсуждать совместимость с GNU/Linux и то, как в этой системе настроить ту или иную функцию и, периодически, меня таки просят поделиться конфигами. Под влиянием этих самых обсуждений и родилась данная статья.
Большую часть своего компьютерного стажа я пользуюсь лаптопами так называемой «бизнес серии»: IBM ThinkPad 600, HP-Compaq nc2400, Lenovo ThinkPad X61T, Lenovo ThinkPad X220.

Были кратковременные перерывы, когда приходилось перебиваться абы-чем, то бишь компьютерами потребительского сегмента: Apple ibook G4 и Acer aspire 5112 и именно в эти моменты приходило понимание того, как сильно не хватает таких очевидных и привычных вещей, как трекпоинт и док-станция.
Что это такое? Подставка для лаптопа с разъемом питания и всевозможными дополнительными портами. В некоторые модели можно установить дополнительный жесткий диск или аккумулятор. Док-станция избавляет от необходимости каждый раз подключать весь набор кабелей, приходя на рабочее место и отсоединять, уходя.
Особенно удобна такая конфигурация под управлением GNU/Linux (в моем случае, Debian stable), где несколькими скриптами можно детально описать поведение компьютера.
Описание сценария работы
На работе я использую конфигурацию с внешним монитором и bluetooth клавиатурой Lenovo ThinkPad kt1255. Лаптоп практически никогда не выключается, вместо этого используется suspend to ram. Опишу сценарии обработчиков:
— Пробуждение в доке с закрытой крышкой: включить внешний монитор, активировать bluetooth и подключить клавиатуру, cpu performance
— Открытие крышки в доке: погасить внешний монитор и перевести изображение на внутренний
— Извлечение с открытой крышкой: дополнительно отключит клавиатуру и bt, cpu on-demand
— Извлечении с закрытой крышкой: залочить экран, перевести изображение на внутренний экран отключив внешний, вырубить клавиатуру и bt-модуль, cpu в on-demand, перейти в pm-suspend
— Закрытие крышки не в доке: блокировка экрана, pm-suspend
Непосредственно настройка
Какими-либо DE я не пользуюсь, да и не вижу смысла возлагать на них функцию управления питанием. Потому, настраивать будем средствами acpid.
Настройку начинаем, как обычно, с установки нужных программ:
#apt-get install acpid acpi-support cpufrequtils
Далее, смотрим какие события у нас генерятся при отстыковке лаптопа:
#acpi_listen ac_adapter ACPI0003:00 00000080 00000000 ibm/hotkey LEN0068:00 00000080 00006030 thermal_zone LNXTHERM:00 00000081 00000000 battery PNP0C0A:00 00000080 00000001 ibm/hotkey LEN0068:00 00000080 00004011
#acpi_listen ibm/hotkey LEN0068:00 00000080 00004010 ac_adapter ACPI0003:00 00000080 00000001 ibm/hotkey LEN0068:00 00000080 00006030 thermal_zone LNXTHERM:00 00000081 00000000 battery PNP0C0A:00 00000080 00000001 button/lid LID close
Стоит отметить, что ThinkPad Mini Dock Series 3 не предоставляет proc интерфейса.
Напишем правила для событий:
#vim /etc/acpi/events/thinkpad-dock event=ibm/hotkey LEN0068:00 00000080 00004010 action=/etc/acpi/thinkpad-dock.sh #vim /etc/acpi/events/thinkpad-undock event=ibm/hotkey LEN0068:00 00000080 00004011 action=/etc/acpi/thinkpad-undock.sh
Правило на закрытие крышки идет в комплекте с пакетом acpi-support. Приведем его к надлежащему виду, указав путь к скрипту-обработчику:
#vim /etc/acpi/events/lidbtn event=button[ /]lid action=/etc/acpi/lid.sh
А теперь перейдем к самому интересному: скриптам, описывающим реакцию на события при описанных выше условиях.
#vim /etc/acpi/lid.sh #!/bin/bash #проверяем, подключен ли лаптоп к док-станции grep -q on /etc/tp_dock_state; if [ $? = 0 ] then #если да, проверяем открыта ли крышка grep -q open /proc/acpi/button/lid/*/state if [ $? = 0 ] then #если да, включаем встроенный монитор, гасим внешний DISPLAY=:0.0 su user -c 'xrandr --output LVDS1 --auto' DISPLAY=:0.0 su user -c 'xrandr --output HDMI3 --off' else #если нет, включаем внешний, гасим встороенный DISPLAY=:0.0 su user -c 'xrandr --output HDMI3 --auto' DISPLAY=:0.0 su user -c 'xrandr --output LVDS1 --off' #включаем bluetooth-модуль и запускаем сервис echo enabled> /proc/acpi/ibm/bluetooth /etc/init.d/bluetooth start #подключаем bluetooth клавиатуру. echo 'connect 90:7F:61:10:A3:BC'|bluetoothctl #выставляем переключение раскладки по alt_gr, подгружаем кастомные биндинги DISPLAY=:0.0 su user -c 'setxkbmap -option grp:toggle us,ru' DISPLAY=:0.0 su user -c 'xmodmap ~/.xmodmaprc' fi else #если не подключен grep -q closed /proc/acpi/button/lid/*/state if [ $? = 0 ] then #отключаем отключаем клавиатуру, останавливаем сервис и отключаем bt-модуль echo 'disconnect 90:7F:61:10:A3:BC'|bluetoothctl /etc/init.d/bluetooth stop echo disabled> /proc/acpi/ibm/bluetooth #вызываем с правами пользователя user блокировщик экрана DISPLAY=:0.0 su user -c /home/user/bin/lock #переводим изоражение на встроенный экран DISPLAY=:0.0 su user -c 'xrandr --output LVDS1 --auto' #отключаем внешний DISPLAY=:0.0 su user -c 'xrandr --output HDMI3 --off' #отправляем лаптоп спать pm-suspend #при пробуждении проверяем, в доке ли thinkpad: grep -q closed /proc/acpi/button/lid/*/state if [ $? = 0 ] then #если да, то, сообщаем об этом: echo on >/etc/tp_dock_state #включаем внешний монитор и гасим встроенный DISPLAY=:0.0 su user -c 'xrandr --output HDMI3 --auto' DISPLAY=:0.0 su user -c 'xrandr --output LVDS1 --off' #включаем bt-модуль, запускаем сервис, подключаем bt-клавиатуру echo enabled> /proc/acpi/ibm/bluetooth /etc/init.d/bluetooth start echo 'connect 90:7F:61:10:A3:BC'|bluetoothctl #подгружаем раскладку и биндинги DISPLAY=:0.0 su user -c 'setxkbmap -option grp:toggle us,ru' DISPLAY=:0.0 su user -c 'xmodmap ~/.xmodmaprc &' fi else #если нет, то просто включаем встроенный экран DISPLAY=:0.0 su user -c 'xrandr --output LVDS1 --auto' fi
Поясню, на всякий случай, что 90:7F:61:10:A3:BC — это адрес моей клавиатуры. Настраиваются bluetooth устройства достаточно просто:
#apt-get install bluez #bluetoothctl [NEW] Controller 40:2C:F4:BB:3C:FC nethack [default] [bluetooth]# agent on Agent registered [bluetooth]# default-agent Default agent request successful [bluetooth]# scan on Discovery started [CHG] Controller 40:2C:F4:BB:3C:FC nethack [default] [NEW] Device 90:7F:61:10:A3:BC ThinkPad Compact Bluetooth Keyboard with TrackPoint [bluetooth]# pair 90:7F:61:10:A3:BC Attempting to pair with 90:7F:61:10:A3:BC [CHG] Device 90:7F:61:10:A3:BC Connected: yes [agent] PIN code: 12345 #вводим с клавиатуры PIN [bluetooth]# connect 90:7F:61:10:A3:BC Attempting to connect to 90:7F:61:10:A3:BC Connection successful
В дальнейшем, когда устройства связаны, достаточно передать
#echo 'connect 90:7F:61:10:A3:BC'| bluetoothctl
Чем мы в скриптах и пользуемся.
Опишем обработчик стыковки:
#vim /etc/acpi/thinkpad-dock.sh #!/bin/sh #сообщаем о стыковке echo on >/etc/tp_dock_state #переводим процессор в режим performance cpufreq-set -c 0 -g performance cpufreq-set -c 1 -g performance cpufreq-set -c 2 -g performance cpufreq-set -c 3 -g performance #подключаем клавиатуру, на случай, если мы куда-нибудь уносили лаптоп echo 'connect 90:7F:61:10:A3:BC'|bluetoothctl
#vim /etc/acpi/thinkpad-undock.sh #!/bin/bash #сообщаем об отстыковке echo off >/etc/tp_dock_state #переводим процессор в экономичный режим cpufreq-set -c 0 -g powersave cpufreq-set -c 1 -g powersave cpufreq-set -c 2 -g powersave cpufreq-set -c 3 -g powersave #проверяем, закрыта ли крышка: grep -q closed /proc/acpi/button/lid/*/state if [ $? = 0 ] then #если да, то вызываем локскрин DISPLAY=:0.0 su user -c /home/user/bin/lock #отключаем bt-клавиатуру, останавливаем сервис, отключаем модуль echo 'disconnect 90:7F:61:10:A3:BC'|bluetoothctl /etc/init.d/bluetooth stop echo disabled> /proc/acpi/ibm/bluetooth #переклюочаем изображение на встроенный экран DISPLAY=:0.0 su user -c 'xrandr --output LVDS1 --auto' DISPLAY=:0.0 su user -c 'xrandr --output HDMI3 --off' #усыпляем лаптоп pm-suspend #после пробуждения вновь проверяем, закрыта ли крышка grep -q closed /proc/acpi/button/lid/*/state if [ $? = 0 ] then #если да, то включаем внешний монитор и выключаем внутренний DISPLAY=:0.0 su user -c 'xrandr --output HDMI3 --auto' DISPLAY=:0.0 su user -c 'xrandr --output LVDS1 --off' #включаем bt-модуль, запускаем сервис, подключаем клавиатуру echo enabled> /proc/acpi/ibm/bluetooth /etc/init.d/bluetooth start echo 'connect 90:7F:61:10:A3:BC'|bluetoothctl #сообщаем о стыковке echo on >/etc/tp_dock_state fi fi
Подводные камни
После обновления до debian 8, где в системе появился systemd, я столкнулся со следующей проблемой: при закрытии крышки, pm-suspend почему-то отрабатывал два раза. То есть выполнялся скрипт lid.sh, но параллельно с ним производилось действие pm-suspend без всяких скриптовых обвязок.
Главным подозреваемым, конечно же, стал новый инициализационный комбайн. И не зря: после десяти минут гугления выяснилось, что, оказывается, systemd пытается, до кучи, брать на себя и функцию по управлению событиями acpi, но делает это покамест не слишком хорошо: на данный момент не может обрабатывать события подключения адаптера питания и батареи.
Переписывать скрипты под новые веяния моды желание также не возникло, потому было проделано следующее:
#sed -i 's/HandleLidSwitch=yes/HandleLidSwitch=ignore/' /etc/systemd/logind.conf
Тем самым мы отучили systemd делать то, о чем не просят и все встало на круги своя. В принципе, то же самое стоит сделать с HandleSuspendKey, HandleHibernateKey и HandlePowerKey, если есть желание обрабатывать нажатия через acpid.
Заключение
Таким образом, получаем удобную конфигурацию, не требующую каких-то лишних рутинных манипуляций. Приходя утром на работу, я достаю лаптоп из рюкзака, вставляю его в док-станцию и нажимаю кнопку питания на этой самой док-станции, после чего работаю как со стационарным компьютером. Уходя, просто жму кнопку отстыковки и убираю компьютер в рюкзак.
Недостаток у такого подхода ровно один: вызывает сильное привыкание.
какая разница между acpid и logind от systemd?
и почему у меня в системе работают оба? Это нормально?

dikiy ★★☆☆☆
29.12.18 20:33:44 MSK

а в чём связь? это вообще разные вещи
eternal_sorrow ★★★★★
( 29.12.18 20:34:53 MSK )
Ответ на: комментарий от eternal_sorrow 29.12.18 20:34:53 MSK

события от acpi кто обрабатывает? logind или acpid? Потому что например в logind.conf однозначно указывается что делать при закрытии крышки ноута, или при нажатии на кнопку питания.
dikiy ★★☆☆☆
( 29.12.18 20:40:06 MSK ) автор топика
Выруби acpid и посмотри что изменится
Deleted
( 29.12.18 20:42:03 MSK )
Ответ на: комментарий от Deleted 29.12.18 20:42:03 MSK

вроде вырубил, и ничего не поменялось. Точнее может поменялось, но я не замечаю этого.
dikiy ★★☆☆☆
( 29.12.18 20:42:36 MSK ) автор топика
Последнее исправление: dikiy 29.12.18 20:42:55 MSK (всего исправлений: 1)
Ответ на: комментарий от dikiy 29.12.18 20:42:36 MSK
Значит, оно и не нужно. У меня такого процесса нет в системе.
Deleted
( 29.12.18 20:44:11 MSK )
Ответ на: комментарий от dikiy 29.12.18 20:40:06 MSK

оба. но в logind настройка всего этого добра довольно негибкая, и к тому же это не все возможные события ACPI
eternal_sorrow ★★★★★
( 29.12.18 20:44:11 MSK )
Ответ на: комментарий от eternal_sorrow 29.12.18 20:44:11 MSK

оба. но в logind настройка всего этого добра довольно негибкая, и к тому же это не все возможные события ACPI
а искаропки acpid ставится? я просто не знаю, искаропки оно у меня или нет. И вообще что оно делает тогда? В /etc/acpi/events пусто
dikiy ★★☆☆☆
( 29.12.18 20:46:11 MSK ) автор топика
Ответ на: комментарий от dikiy 29.12.18 20:46:11 MSK

в какой ОС? в моей искаробки нет ни acpid ни systemd
eternal_sorrow ★★★★★
( 29.12.18 20:47:39 MSK )
Ответ на: комментарий от eternal_sorrow 29.12.18 20:47:39 MSK

а, сорян. В Mint MATE
dikiy ★★☆☆☆
( 29.12.18 20:48:37 MSK ) автор топика
Ответ на: комментарий от dikiy 29.12.18 20:46:11 MSK

что настроишь, то и делает. смотри скрипты в директории /etc/acpi/
eternal_sorrow ★★★★★
( 29.12.18 20:50:46 MSK )
Последнее исправление: eternal_sorrow 29.12.18 20:51:24 MSK (всего исправлений: 1)
Ответ на: комментарий от eternal_sorrow 29.12.18 20:50:46 MSK

что настроишь, то и делает. смотри скрипты в папке /etc/acpi/
но чтобы они вызывались, надо чтобы в events что-то лежало. А там нет ничего.
А не, есть. Ок, значит оставим эту штуку.