acpid (Español)

From ArchWiki
Jump to: navigation, search

acpid es un "demonio" flexible y extensible para entregar eventos ACPI. Vigila /proc/acpi/event y cuando hay un evento, ejecuta programas para manejarlo. Estos eventos se activan mediante ciertas acciones, como:

  • Presionar teclas especiales, incluyendo el botón de Encendido/Hibernar/Suspender.
  • Cerrando la tapa del portátil
  • Desconectar un adaptador de Corriente Alterna a un portátil.
  • Desconectar un jack de un teléfono, etc.

acpid puede ser usado así mismo, o combinado con un sistema más robusto como pm-utils y cpufrequtils para una mayor solución del control de energía.

Nota:
  • Entornos de escritorio, como GNOME, gestor de inicio de sesión de systemd[broken link: invalid section] y algunos demonios manejadores de teclas extra pueden implementar métodos propios de manejo de eventos, independientemente de acpid. Usar más de un sistema a la vez puede provocar un comportamiento inesperado, como suspenderse dos veces de una, tras apretar una vez el botón de hibernar. Ten esto en cuenta y activa solo manejadores deseados.
  • Ya que por defecto el script que provee acpid, /etc/acpi/handler.sh, sobrescribirá la funcionalidad del botón de encendido/apagado de tu entorno de escritorio, seguramente querrás cambiar la rutina de apagado de acpid para evitar apagar el ordenador cuando presiones de golpe el botón de encendido/apagado (ver instrucciones a continuación).

Instalación

Instala el paquete acpid, disponible en los repositorios oficiales.

Para que empiece el arranque :

  • Si usas systemd (seguramente), ingresa en un terminal systemctl enable acpid ;
  • Si usas initscripts, edita /etc/rc.conf como superusuario y añade acpid a la variable DAEMONS.

Configuración

acpid viene con un número de acciones predefinidas para eventos activos, como lo qué debería occurrir cuando se presiona el botón de encendido/apagado en el ordenador. Por defecto, esas acciones están definidas en /etc/acpi/handler.sh, que se ejecuta después de que se detecta un evento ACPI (según determine /etc/acpi/events/anything).

Lo siguiente es un ejemplo de una acción. En este caso, cuando se presiona el botón de Hibernar, acpid ejecuta el comando echo -n mem >/sys/power/state, que debería poner el ordenador en un estado de hibernación (suspendido):

button/sleep)
    case "$2" in
        SLPB) echo -n mem >/sys/power/state ;;
	 *)    logger "ACPI action undefined: $2" ;;
    esac
    ;;

Desafortunadamente, no todos los ordenadores etiquetan los eventos ACPI de la misma forma. Por ejemplo, el botón Hibernar puede identificarse en un PC como SLPB y en otra como SBTN.

Para determinar como son reconocidos tus botones o atajos de teclado, ejecuta el siguiente comando en un terminal como root:

# tail -f /var/log/messages.log

Ahora presione el botón de Encendido y/o el botón de Hibernar (p. ej. Ctrl+Alt+Supr) de la PC. El resultado debería ser algo asi:

logger: ACPI action undefined: PBTN
logger: ACPI action undefined: SBTN

Si no funciona, intenta:

# acpi_listen

Entonces presione el botón de Encendido/Apagado y se verá algo así:

power/button PBTN 00000000 00000b31

La salida de acpi_listen se envía a /etc/acpi/handler.sh como parámetros $1, $2 , $3 & $4.. Ejemplo:

$1 power/button
$2 PBTN
$3 00000000
$4 00000b31

Como se puede observar, el botón de Hibernar en la salida de ejemplo es reconocido como SBTN, en lugar de la etiqueta SLPB especificada en archivo /etc/acpi/handler.sh por defecto. Para hacer que el botón de Hibernar funcione correctamente en el PC, necesitaremos reemplazar SLPB) con SBTN).

Usando esto como base, se puede personalizar fácilmente el archivo /etc/acpi/handler.sh para ejecutar una variedad de comandos dependiendo de que evento es ejecutado. Mira la sección #Trucos y Sugerencias a continuación para otros comandos usados comúnmente.

Configuración alternativa

Por defecto, todos los eventos ACPI pasan por el script /etc/acpi/handler.sh. Esto se debe al conjunto de reglas escritas en /etc/acpi/events/anything:

# Pass all events to our one handler script
event=.*
action=/etc/acpi/handler.sh %e

Aunque esto funciona muy bien como está, algunos usuarios pueden preferir definir reglas de evento y acciones en sus propios scrpits independientes. Lo siguiente es un ejemplo de cómo usar un archivo de evento individual y su correspondiente script de acción:

Como superusuario, crea el archivo siguiente:

/etc/acpi/events/sleep-button
event=button sleep.*
action=/etc/acpi/actions/sleep-button.sh "%e"

Ahora crea el siguinte archivo:

/etc/acpi/actions/sleep-button.sh
#!/bin/sh
case "$2" in
    SLPB) echo -n mem >/sys/power/state ;;
    *)    logger "ACPI action undefined: $2" ;;
esac

Finalmente, haz el script ejecutable:

# chmod +x /etc/acpi/actions/sleep-button.sh

Usando este método, es fácil crear los scripts de eventos/acciones individuales que quieras.

Trucos y Sugerencias

Sugerencia: Algunas acciones descritas aquí, como el control del Wi-Fi y del brillo, pueden ser controlados directamente por los drivers. Deberías consultar la documentación de los módulos del kernel correspondientes cuando este sea el caso.

Ampliando acpid con pm-utils

Aunque acpid puede proveer una función de suspendido básica, se podría desear un sistema más robusto. pm-utils provee una estructura muy flexible suspender e hibernar, incluyendo soluciones para hardware y drivers tercos (p. ej. módulos fglrx). pm-utils provee dos scripts, pm-suspend y pm-hibernate, los cuales pueden ser insertados como eventos en acpid. Para más información lee el wiki pm-utils wiki.

Eventos de Ejemplo

Los siguientes son ejemplos de eventos que pueden ser usados en el script /etc/acpi/handler.sh. Estos ejemplos deberían ser modificados para que se ajusten a el entorno específico, por ejemplo cambiando los nombres de las variables de evento tal y como las interprete acpi_listen.

Para bloquear la pantalla con xscreensaver cuando se cierra la tapa del portátil intenta:

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
            ;;

Para suspender el sistema y bloquear la pantalla usando slimlock cuando la tapa está cerrada:

button/lid)
    case $3 in
        close)
            #echo "LID switched!">/dev/tty5
	     /usr/sbin/pm-suspend &
	     DISPLAY=:0.0 su -c - username /usr/bin/slimlock
            ;;

Ejecuta pm-suspend cuando se presiona el botón de suspensión.

button/sleep)
    case "$2" in
        SBTN) 
	     #echo -n mem >/sys/power/state
            /usr/sbin/pm-suspend
            ;;

Para ajustar el brillo del portátil según este conectado a la corriente o no (se debería ajustar los números, mira /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

Activar el control del volumen

Descubre la identificación de acpi de los botones de volumen (mira a continuación) y sustituye los eventos acpi en los archivos a continuación. Creamos un script para controlar el volumen (asumiendo que se usa una tarjeta de sonido con ALSA (Español)):

/etc/acpi/handlers/vol
#!/bin/sh
step=5

case $1 in
  -) amixer set Master $step-;;
  +) amixer set Master $step+;;
esac

Y conectalos a nuevos eventos acpi:

/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 +

También otro evento para silenciar:

/etc/acpi/events/mute
event=button/mute
action=/usr/bin/amixer set Master toggle

Activar el control del brillo

Parecido al control del volumen, acpid también permite controlar el brillo de la pantalla. Para conseguir esto escribe un script como el siguiente:

/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

y otra vez, conecta las teclas a eventos 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 +

Habilitar el control del Wi-Fi

También se puede crear un sencillo controlador wireless presionando los botones WLAN. Un ejemplo de evento:

/etc/acpi/events/wlan
event=button/wlan
action=/etc/acpi/handlers/wlan

y su script manejador:

/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

Apagar la pantalla del portátil

Adaptado del de Gentoo, viene esta pequeña perla. Añade esto al final de /etc/acpi/actions/lm_lid.sh o a la sección button/lid /etc/acpi/handler.sh. Esto apagará la luz de la pantalla cuando la tapa esté cerrada, y la encenderá cuando la tapa se abra.

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

Si se quiere incrementar/disminuir el brillo o algo que dependa de X, se debe especificar el monitor con X y también el archivo MIT magic cookie (via XAUTHORITY). Lo último es una credencial de seguridad que provee acceso de escritura y lectura al servidor X, monitor, y dispositivos de entrada.

Aquí hay otro script que no usa XAUTHORITY sino 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

Con ciertas combinaciones de Xorg y hardware problemático, xset dpms force off solo deja en blanco la pantalla dejando la luz encendida. Esto puede ser corregido usando vbetool de los repositorios oficiales. Cambia la sección LCD a:

case $(cat /proc/acpi/button/lid/LID0/state | awk '{print $2}') in
    closed) vbetool dpms off ;;
    open)   vbetool dpms on  ;;
esac

Si el monitor se apaga solo brevemente y después se enciende, seguramente sea el control de energía que viene con xscreensaver, que entra en conflicto con los ajustes manuales de dpm'.

Sacar el nombre de usuario del monitor actual

Se puede usar la función getuser para descubrir el usuario del monitor actual:

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
    }

Se puede usar esta función, por ejemplo, cuando se presiona el botón de Encendido/Apagado, y se requiere apagar KDE correctamente:

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
    ;;


En sistemas más nuevos usando systemd, los accesos a X11 no son necesariamente mostrados en who, de manera que la función getuser no sirve. Una alternativa es usar loginctl para obtener la información requerida (p.ej. usando xuserrun.

Ver también