# acpid (Español)

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

- http://acpid.sourceforge.net/ - página de acpid
- Gentoo wiki
- ACPI hotkeys

Category:

- Power management (Español)

Hidden category:

- Pages with broken section links