Difference between revisions of "Acpid"
m (I think it's worth a warning (+ some style fixes)) |
Eruditorum (talk | contribs) (→Enabling Wi-fi toggle) |
||
(37 intermediate revisions by 17 users not shown) | |||
Line 1: | Line 1: | ||
{{lowercase title}} | {{lowercase title}} | ||
[[Category:Power management]] | [[Category:Power management]] | ||
− | [[ | + | [[it:Acpid]] |
− | + | [[zh-CN:Acpid]] | |
− | [http://acpid.sourceforge.net/ acpid] is a flexible and extensible daemon for delivering ACPI events. These events are triggered by certain actions, such as: | + | [http://acpid.sourceforge.net/ acpid] is a flexible and extensible daemon for delivering [[ACPI modules|ACPI events]]. It listens on {{ic|/proc/acpi/event}} and when an event occurs, executes programs to handle the event. These events are triggered by certain actions, such as: |
− | * Pressing the Power | + | * Pressing special keys, including the Power/Sleep/Suspend button |
− | |||
* Closing a notebook lid | * Closing a notebook lid | ||
* (Un)Plugging an AC power adapter from a notebook | * (Un)Plugging an AC power adapter from a notebook | ||
+ | * (Un)Plugging phone jack etc. | ||
+ | |||
acpid can be used by itself, or combined with a more robust system such as [[pm-utils]] and [[CPU Frequency Scaling|cpufrequtils]] to provide a more complete power management solution. | acpid can be used by itself, or combined with a more robust system such as [[pm-utils]] and [[CPU Frequency Scaling|cpufrequtils]] to provide a more complete power management solution. | ||
− | {{ | + | {{Note| |
+ | * [[Desktop Environment|desktop environments]], such as [[GNOME]], [[Systemd#ACPI power management|systemd]] login manager and some [[Extra Keyboard Keys|extra key handling]] daemons may implement own event handling schemes, independent of acpid. Running more than one system at the same time may lead to unexpected behaviour, such as suspending two times in a row after one sleep button press. You should be aware of this and only activate desirable handlers. | ||
+ | * Since by default the script provided by acpid, '''/etc/acpi/handler.sh''', will override your desktop environment's power button functionality, you most likely want to change acpid's power off routine to avoid shutting down the system suddenly when you press the power button (see instructions below).}} | ||
== Installation == | == Installation == | ||
Line 17: | Line 20: | ||
[[pacman|Install]] the {{Pkg|acpid}} package, available in the [[Official Repositories|official repositories]]. | [[pacman|Install]] the {{Pkg|acpid}} package, available in the [[Official Repositories|official repositories]]. | ||
− | + | To have it start on boot : | |
+ | * if you're using [[systemd]], run {{ic|systemctl enable acpid}} ; | ||
+ | * if you're using [[rc.conf|initscripts]], edit {{ic|/etc/rc.conf}} as root and add {{ic|acpid}} to the [[rc.conf#Daemons|DAEMONS array]]. | ||
== Configuration == | == Configuration == | ||
Line 105: | Line 110: | ||
# See: man xscreensaver-command. $xs will have the value of the user owning the process, if any. | # See: man xscreensaver-command. $xs will have the value of the user owning the process, if any. | ||
− | xs=$(ps | + | xs=$(ps -C xscreensaver -o user=) |
if test $xs; then su $xs -c "xscreensaver-command -lock"; fi | if test $xs; then su $xs -c "xscreensaver-command -lock"; fi | ||
;; | ;; | ||
Line 141: | Line 146: | ||
;; | ;; | ||
esac | esac | ||
+ | |||
+ | === Enabling volume control === | ||
+ | |||
+ | Find out the acpi identity of the volume buttons (see above) and susbtitute it for the acpi events in the files below. We create a script to control the volume (assuming an [[ALSA]] sound card): | ||
+ | |||
+ | {{hc|/etc/acpi/handlers/vol|<nowiki> | ||
+ | #!/bin/sh | ||
+ | step=5 | ||
+ | |||
+ | case $1 in | ||
+ | -) amixer set Master $step-;; | ||
+ | +) amixer set Master $step+;; | ||
+ | esac | ||
+ | </nowiki>}} | ||
+ | |||
+ | and connect these to new acpi events: | ||
+ | |||
+ | {{hc|/etc/acpi/events/vol_d|<nowiki> | ||
+ | event=button/volumedown | ||
+ | action=/etc/acpi/handlers/vol - | ||
+ | </nowiki>}} | ||
+ | {{hc|/etc/acpi/events/vol_u|<nowiki> | ||
+ | event=button/volumeup | ||
+ | action=/etc/acpi/handlers/vol + | ||
+ | </nowiki>}} | ||
+ | |||
+ | as well as another event to toggle the mute setting: | ||
+ | |||
+ | {{hc|/etc/acpi/events/mute|<nowiki> | ||
+ | event=button/mute | ||
+ | action=/usr/bin/amixer set Master toggle | ||
+ | </nowiki>}} | ||
+ | |||
+ | === Enabling backlight control === | ||
+ | |||
+ | Similar to volume control, acpid also enables you to control screen backlight. To achieve this you write some handler, like this: | ||
+ | |||
+ | {{hc|/etc/acpi/handlers/bl|<nowiki> | ||
+ | #!/bin/sh | ||
+ | bl_dev=/sys/class/backlight/acpi_video0 | ||
+ | step=1 | ||
+ | |||
+ | case $1 in | ||
+ | -) echo $((`cat $bl_dev/brightness` - $step)) >$bl_dev/brightness;; | ||
+ | +) echo $((`cat $bl_dev/brightness` + $step)) >$bl_dev/brightness;; | ||
+ | esac | ||
+ | </nowiki>}} | ||
+ | |||
+ | and again, connect keys to ACPI events: | ||
+ | |||
+ | {{hc|/etc/acpi/events/bl_d|<nowiki> | ||
+ | event=video/brightnessdown | ||
+ | action=/etc/acpi/handlers/bl - | ||
+ | </nowiki>}} | ||
+ | {{hc|/etc/acpi/events/bl_u|<nowiki> | ||
+ | event=video/brightnessup | ||
+ | action=/etc/acpi/handlers/bl + | ||
+ | </nowiki>}} | ||
+ | |||
+ | === Enabling Wi-fi toggle === | ||
+ | |||
+ | You can also create a simple wireless-power switch by pressing the WLAN button. Example of event: | ||
+ | |||
+ | {{hc|/etc/acpi/events/wlan|<nowiki> | ||
+ | event=button/wlan | ||
+ | action=/etc/acpi/handlers/wlan | ||
+ | </nowiki>}} | ||
+ | |||
+ | and its' handler: | ||
+ | |||
+ | {{hc|/etc/acpi/handlers/wlan|<nowiki> | ||
+ | #!/bin/sh | ||
+ | rf=/sys/class/rfkill/rfkill0 | ||
+ | |||
+ | case `cat $rf/state` in | ||
+ | 0) echo 1 >$rf/state && systemctl start net-auto-wireless;; | ||
+ | 1) systemctl stop net-auto-wireless && echo 0 >$rf/state;; | ||
+ | esac | ||
+ | </nowiki>}} | ||
=== Laptop Monitor Power Off === | === Laptop Monitor Power Off === | ||
Line 151: | Line 235: | ||
If you would like to increase/decrease brightness or anything dependent on X, you should specify the X display as well as the MIT magic cookie file (via XAUTHORITY). The last is a security credential providing read and write access to the X server, display, and any input devices. | If you would like to increase/decrease brightness or anything dependent on X, you should specify the X display as well as the MIT magic cookie file (via XAUTHORITY). The last is a security credential providing read and write access to the X server, display, and any input devices. | ||
+ | |||
+ | Here is another script not using XAUTHORITY but sudo: | ||
+ | |||
+ | case $(cat /proc/acpi/button/lid/LID0/state | awk '{print $2}') in | ||
+ | closed) sudo -u `ps -o ruser= -C xinit` xset -display :0 dpms force off ;; | ||
+ | open) sudo -u `ps -o ruser= -C xinit` xset -display :0 dpms force on ;; | ||
+ | esac | ||
With certain combinations of [[Xorg]] and stubborn hardware, {{ic|xset dpms force off}} only blanks the display leaving the backlight turned on. This can be fixed using {{Pkg|vbetool}} from the [[Official Repositories|official repositories]]. Change the LCD section to: | With certain combinations of [[Xorg]] and stubborn hardware, {{ic|xset dpms force off}} only blanks the display leaving the backlight turned on. This can be fixed using {{Pkg|vbetool}} from the [[Official Repositories|official repositories]]. Change the LCD section to: | ||
Line 181: | Line 272: | ||
esac | esac | ||
;; | ;; | ||
+ | |||
+ | |||
+ | On newer systems using systemd, X11 logins are no longer necessarily displayed in {{ic|who}}, so the {{ic|getuser}} function above does not work. An alternative is to use {{ic|loginctl}} to obtain the required information, e.g. using [https://github.com/rephorm/xuserrun xuserrun]. | ||
==See also== | ==See also== | ||
Line 186: | Line 280: | ||
* http://acpid.sourceforge.net/ - acpid homepage | * http://acpid.sourceforge.net/ - acpid homepage | ||
* http://www.gentoo-wiki.info/ACPI/Configuration - RIP Gentoo wiki entry - New Gentoo Wiki Archives | * http://www.gentoo-wiki.info/ACPI/Configuration - RIP Gentoo wiki entry - New Gentoo Wiki Archives | ||
+ | * [[ACPI hotkeys]] |
Revision as of 00:08, 19 February 2013
acpid is a flexible and extensible daemon for delivering ACPI events. It listens on /proc/acpi/event
and when an event occurs, executes programs to handle the event. These events are triggered by certain actions, such as:
- Pressing special keys, including the Power/Sleep/Suspend button
- Closing a notebook lid
- (Un)Plugging an AC power adapter from a notebook
- (Un)Plugging phone jack etc.
acpid can be used by itself, or combined with a more robust system such as pm-utils and cpufrequtils to provide a more complete power management solution.
- desktop environments, such as GNOME, systemd login manager and some extra key handling daemons may implement own event handling schemes, independent of acpid. Running more than one system at the same time may lead to unexpected behaviour, such as suspending two times in a row after one sleep button press. You should be aware of this and only activate desirable handlers.
- Since by default the script provided by acpid, /etc/acpi/handler.sh, will override your desktop environment's power button functionality, you most likely want to change acpid's power off routine to avoid shutting down the system suddenly when you press the power button (see instructions below).
Installation
Install the acpid package, available in the official repositories.
To have it start on boot :
- if you're using systemd, run
systemctl enable acpid
; - if you're using initscripts, edit
/etc/rc.conf
as root and addacpid
to the DAEMONS array.
Configuration
acpid comes with a number of predefined actions for triggered events, such as what should happen when you press the Power button on your machine. By default, these actions are defined in /etc/acpi/handler.sh
, which is executed after any ACPI events are detected (as determined by /etc/acpi/events/anything
).
The following is a brief example of one such action. In this case, when the Sleep button is pressed, acpid runs the command echo -n mem >/sys/power/state
which should place the computer into a sleep (suspend) state:
button/sleep) case "$2" in SLPB) echo -n mem >/sys/power/state ;; *) logger "ACPI action undefined: $2" ;; esac ;;
Unfortunately, not every computer labels ACPI events in the same way. For example, the Sleep button may be identified on one machine as SLPB and on another as SBTN.
To determine how your buttons or Template:Keypress shortcuts are recognized, run the following command from a terminal as root:
# tail -f /var/log/messages.log
Now press the Power button and/or Sleep button (e.g. Template:Keypress) on your machine. The result should look something this:
logger: ACPI action undefined: PBTN logger: ACPI action undefined: SBTN
If that does not work, run:
# acpi_listen
Then press the power button and you will see something like this:
power/button PBTN 00000000 00000b31
The output of acpi_listen
is sent to /etc/acpi/handler.sh
as $1, $2 , $3 & $4 parameters.
Example:
$1 power/button $2 PBTN $3 00000000 $4 00000b31
As you might have noticed, the Sleep button in the sample output is actually recognized as SBTN, rather than the SLPB label specified in the default /etc/acpi/handler.sh
. In order for Sleep function to work properly on this machine, we would need to replace SLPB) with SBTN).
Using this information as a base, you can easily customize the /etc/acpi/handler.sh
file to execute a variety of commands depending on which event is triggered. See the Tips & Tricks section below for other commonly used commands.
Alternative configuration
By default, all ACPI events are passed through the /etc/acpi/handler.sh
script. This is due to the ruleset outlined in /etc/acpi/events/anything
:
# Pass all events to our one handler script event=.* action=/etc/acpi/handler.sh %e
While this works just fine as it is, some users may prefer to define event rules and actions in their own self-contained scripts. The following is an example of how to use an individual event file and corresponding action script:
As root, create the following file:
/etc/acpi/events/sleep-button
event=button sleep.* action=/etc/acpi/actions/sleep-button.sh "%e"
Now create the following file:
/etc/acpi/actions/sleep-button.sh
#!/bin/sh case "$2" in SLPB) echo -n mem >/sys/power/state ;; *) logger "ACPI action undefined: $2" ;; esac
Finally, make the script executable:
# chmod +x /etc/acpi/actions/sleep-button.sh
Using this method, it is easy to create any number of individual event/action scripts.
Tips and tricks
Extending acpid with pm-utils
Although acpid can provide basic suspend2ram out-of-the-box, a more robust system may be desired. pm-utils provides a very flexible framework for suspend2ram (suspend) and suspend2disk (hibernate) operations, including common fixes for stubborn hardware and drivers (e.g. fglrx module). pm-utils provides two scripts, pm-suspend
and pm-hibernate
, both of which can be inserted as events into acpid. For more information, check the pm-utils wiki.
Example Events
The following are examples of events that can be used in the /etc/acpi/handler.sh
script. These examples should be modified so that they apply your specific environment e.g. changing the event variable names interpreted by acpi_listen
.
To lock the screen with xscreensaver
when closing the laptop lid:
button/lid) case $3 in close) # The lock command need to be run as the user who owns the xscreensaver process and not as root. # See: man xscreensaver-command. $xs will have the value of the user owning the process, if any. xs=$(ps -C xscreensaver -o user=) if test $xs; then su $xs -c "xscreensaver-command -lock"; fi ;;
To suspend the system and lock the screen using slimlock
when the lid is closed:
button/lid) case $3 in close) #echo "LID switched!">/dev/tty5 /usr/sbin/pm-suspend & DISPLAY=:0.0 su -c - username /usr/bin/slimlock ;;
Execute pm-suspend
when the sleep button is pressed:
button/sleep) case "$2" in SBTN) #echo -n mem >/sys/power/state /usr/sbin/pm-suspend ;;
To set the laptop screen brightness when plugged in power or not (the numbers might need to be adjusted, see /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
Enabling volume control
Find out the acpi identity of the volume buttons (see above) and susbtitute it for the acpi events in the files below. We create a script to control the volume (assuming an ALSA sound card):
/etc/acpi/handlers/vol
#!/bin/sh step=5 case $1 in -) amixer set Master $step-;; +) amixer set Master $step+;; esac
and connect these to new acpi events:
/etc/acpi/events/vol_d
event=button/volumedown action=/etc/acpi/handlers/vol -
/etc/acpi/events/vol_u
event=button/volumeup action=/etc/acpi/handlers/vol +
as well as another event to toggle the mute setting:
/etc/acpi/events/mute
event=button/mute action=/usr/bin/amixer set Master toggle
Enabling backlight control
Similar to volume control, acpid also enables you to control screen backlight. To achieve this you write some handler, like this:
/etc/acpi/handlers/bl
#!/bin/sh bl_dev=/sys/class/backlight/acpi_video0 step=1 case $1 in -) echo $((`cat $bl_dev/brightness` - $step)) >$bl_dev/brightness;; +) echo $((`cat $bl_dev/brightness` + $step)) >$bl_dev/brightness;; esac
and again, connect keys to ACPI events:
/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 +
Enabling Wi-fi toggle
You can also create a simple wireless-power switch by pressing the WLAN button. Example of event:
/etc/acpi/events/wlan
event=button/wlan action=/etc/acpi/handlers/wlan
and its' handler:
/etc/acpi/handlers/wlan
#!/bin/sh rf=/sys/class/rfkill/rfkill0 case `cat $rf/state` in 0) echo 1 >$rf/state && systemctl start net-auto-wireless;; 1) systemctl stop net-auto-wireless && echo 0 >$rf/state;; esac
Laptop Monitor Power Off
Adapted from the Gentoo Wiki comes this little gem. Add this to the bottom of /etc/acpi/actions/lm_lid.sh
or to the button/lid section /etc/acpi/handler.sh
. This will turn off the LCD back-light when the lid is closed, and restart when the lid is opened.
case $(cat /proc/acpi/button/lid/LID0/state | awk '{print $2}') in closed) XAUTHORITY=$(ps -C xinit -f --no-header | sed -n 's/.*-auth //; s/ -[^ ].*//; p') xset -display :0 dpms force off ;; open) XAUTHORITY=$(ps -C xinit -f --no-header | sed -n 's/.*-auth //; s/ -[^ ].*//; p') xset -display :0 dpms force on ;; esac
If you would like to increase/decrease brightness or anything dependent on X, you should specify the X display as well as the MIT magic cookie file (via XAUTHORITY). The last is a security credential providing read and write access to the X server, display, and any input devices.
Here is another script not using XAUTHORITY but sudo:
case $(cat /proc/acpi/button/lid/LID0/state | awk '{print $2}') in closed) sudo -u `ps -o ruser= -C xinit` xset -display :0 dpms force off ;; open) sudo -u `ps -o ruser= -C xinit` xset -display :0 dpms force on ;; esac
With certain combinations of Xorg and stubborn hardware, xset dpms force off
only blanks the display leaving the backlight turned on. This can be fixed using vbetool from the official repositories. Change the LCD section to:
case $(cat /proc/acpi/button/lid/LID0/state | awk '{print $2}') in closed) vbetool dpms off ;; open) vbetool dpms on ;; esac
If the monitor appears to shut off only briefly before being re-powered, very possibly the power management shipped with xscreensaver conflicts with any manual dpms settings.
Getting user name of the current display
You can use the function getuser
to discover the user of the current display:
getuser () { export DISPLAY=`echo $DISPLAY | cut -c -2` user=`who | grep " $DISPLAY" | awk '{print $1}' | tail -n1` export XAUTHORITY=/home/$user/.Xauthority eval $1=$user }
This function can be used for example, when you press the power button and want to shutdown KDE properly:
button/power) case "$2" in PBTN) getuser "$user" echo $user > /dev/tty5 su $user -c "dcop ksmserver ksmserver logout 0 2 0" ;; *) logger "ACPI action undefined $2" ;; esac ;;
On newer systems using systemd, X11 logins are no longer necessarily displayed in who
, so the getuser
function above does not work. An alternative is to use loginctl
to obtain the required information, e.g. using xuserrun.
See also
- http://acpid.sourceforge.net/ - acpid homepage
- http://www.gentoo-wiki.info/ACPI/Configuration - RIP Gentoo wiki entry - New Gentoo Wiki Archives
- ACPI hotkeys