Introducción
Hace un tiempito recorde que no había probado mi UPS, marca APC modelo BackUPS CS500, con Ubuntu (10.10). Pues configuro el gnome-power-manager, toqueteo algo más con gconf-editor, y hago la prueba clave: desenchufo la UPS simulando un corte de luz. Pasa un rato, y nada… nada… y puff, chau sistema, se apagó de golpe nomás. Nada de avisos, nada de hibernación, nada de seguridad
Luego de putear un rato al power-manager (y al gconf-tool, que por algún motivo es como si no me tomara los cambios si no lo seteo como por default u obligatorio) decidí buscar una solución. Y la encontré: apcupsd. Este programa, que se encuentra en los repos. Y si les interesa una interfaz gráfica que muestre datos: gapcmon, también en los repos.
La idea de este post es compartir los scripts de eventos del apcupsd y cómo configurarlo para que hiberne.
Más info
APCUPSD se configura según el modelo de UPS. Para las USB, la configuración es un segundo, un paseo no más. Sé que además funciona con otras marcas, que sean compatibles con APC.
En fin, y ya falta poquito para llegar al punto, este programa se encarga de monitorear el estado de la UPS: estado de batería, conexión, estado de la alimentación eléctrica, etc. Cuando se produce una enventualidad, el serrvicio apcupsd ejecuta el siguiente archivo: /etc/apcupsd/apccontrol. Este script recibe 4 parámetros – de acuerdo al manual -: el primero indica el evento, el segundo indica el modelo de UPS, el tercero indica si la UPS se conecta directamente al equipo (1) o no (0) y la cuarta no está implementada y siempre vale 0.
El script discrimina, con un simple select case, y ejecuta distintos scripts para cada evento, todos ubicados en el mismo directorio. Esto nos permite crear nuestros propios scripts para cada evento, dado que solo vienen algunos pocos creados. Y también nos permite editar los que ya están hechos con facilidad. Y este es el quid de la cuestión.
Estos scripts se deben nombrar como el nombre del evento. Los posibles eventos son, y cito nuevamente al manual:
annoyme
When a shutdown is scheduled, and the time specified on the ANNOYME directive in the apcupsd.conf file expires, this event is generated.
Default: wall a message
changeme
When apcupsd detects that the mains are on, but the battery is not functioning correctly, this event is generated. It is repeated every x hours.
Default: wall a message
commfailure
This event is generated each time the communications line with the computer is severed. This event is not detected on dumb signaling UPSes.
Default: wall a message
commok
After a commfailure event is issued, when the communications to the computer is re-established, this event will be generated.
Default: wall a message
doreboot
This event is depreciated and should not be used.
Default: Shuts down the system using shutdown -h or similar
doshutdown
When the UPS is running on batteries and one of the limits expires (time, run, load), this event is generated to cause the machine to shutdown.
Default: Shuts down the system using shutdown -h or similar
emergency
Called for an emergency system shutdown. (What triggers such a shutdown is unclear…) After completing this event, apcupsd will immediately initiate a doshutdown event.
Default: wall a message
failing
This event is generated when the UPS is running on batteries and the battery power is exhausted. The event following this one will be a shutdown.
Default: wall a message
loadlimit
This event is generated when the battery charge is below the low limit specified in the apcupsd.conf file. After completing this event, apcupsd will immediately initiate a doshutdown event.
Default: wall a message
powerout
This event is generated immediately when apcupsd detects that the UPS has switched to batteries. It may be due to a short powerfailure, an automatic selftest of the UPS, or a longer powerfailure.
Default: wall a message
onbattery
This event is generated 5 or 6 seconds after an initial powerfailure is detected. It means that apcupsd definitely considers the UPS to be on batteries. The onset of this event can be delayed by the ONBATTERYDELAY apcupsd.conf configuration directive.
Default: wall a message
offbattery
This event is generated when the mains return only if the onbattery event has been generated.
Default: wall a message
mainsback
This event is generated when the mains power returns after a powerout condition. The shutdown event may or may not have been generated depending on the parameters you have defined and the length of the power outage.
Default: nothing
remotedown
This event is generated on a slave machine when it detects either that the master has shutdown, or that a onbattery situation exists and the communications line has been severed.
Default: wall a message
runlimit
This event is generated when the MINUTES value defined in the apcupsd.conf file expires while in a power fail condition. The MINUTES is the remaining runtime as internally calculated by the UPS and monitored by apcupsd. After completing this event, apcupsd will immediately initiate a doshutdown event.
Default: wall a message
timeout
This event is generated when the TIMEOUT value defined in the apcupsd.conf file expires while in a power fail condition. It indicates that the total time in a power failure has been exceeded and the machine should be shutdown. After completing this event, apcupsd will immediately initiate a doshutdown event.
Default: wall a message
startselftest
This event is generated when apcupsd detects a self test by the UPS. Normally due to the 6 second onbattery delay default time, self test events are not detected.
Default: nothing
endselftest
This event is generated when the end of a self test is detected.
Default: nothing
battdetach
This event is generated when apcupsd detects that the UPS battery has been disconnected.
Default: nothing
battattach
This event is generated when apcupsd detects that the UPS battery has been reconnected after a battdetach event.
Default: nothing
Nota: Estoy algo cansado para traducir todo, agradecería a quien lo hiciera
Entonces, lo que hice fue generar casi todos estos scripts (salvo algunos que realmente no sirven para nada) y luego cambie las opciones de apagado para que siempre, siempre, hiberne (si es que tu sistema soporta hibernación; de no ser asi, simplemente cambias la configuración por apagado)
En los scripts, mantuve la configuración original, donde se manda un mail al root del sistema avisando de la eventualidad, y agregué una notificación vía notify-osd, usando además íconos por default que todos seguramente tendrán (en Ubuntu); de cualquier forma, los incluyo en la sección de descarga.
Descarga
Les dejo aquí los scripts todos: http://www.multiupload.com/DFA0546FJO
IMPORTANTE:
Hay que hacerles una pequeña modificación: donde dice usuario=”hackan”, deben poner su nombre de usuario. Esto es en cada script. Recuerden que deben ser root para copiarlos a donde corresponde y editarlos.
Los íconos que usé con el notify-send: http://www.multiupload.com/5FBZD1Q9H6
Para instalar apcupsd: sudo apt-get install apcupsd
Para instalar gapcmon: sudo apt-get install gapcmon
Configurando
Vamos a configurar, entonces, apcupsd. Supondré que tenés una UPS de la marca APC; de no ser así, deberías averiguar si este programa te sirve, y cómo configurarlo.
Hay que editar el archivo apcupsd.conf: sudo vim /etc/apcupsd/apcupsd.conf
Si no tienes vim, puedes usar nano, gedit, leafpad o cualquier editor de texto de tu agrado: sudo gedit /etc/apcupsd/apcupsd.conf
Por defecto, este archivo ya tiene una guía escrita que es muy sencilla de seguir. Lo haremos paso a paso, siguiendo esa guía.
La primer opción es UPSNAME. Allí ponen un nombre corto para nombrar a su UPS; debe tener menos de 8 caracteres, p.e.: APCCS500 en mi caso.
La segunda es UPSCABLE. Aquí deben definir cómo se comunica la UPS con la PC. Hay cuatro opciones: usb (mi caso), simple, smart, ether. Ether se refiere a una conexión vía ethernet, es decir, red. Smart y Simple son cables que se conectan vía puerto serie.
La tercera: UPSTYPE y DEVICE. Aquí hay varias opciones, pero casi seguro se reducen a dos: para conexión USB y para conexión serie.
Para USB:
UPSTYPE usb DEVICE
IMPORTANTE: luego de la palabra DEVICE hay un espacio! esto es muy importante, deben poner ese espacio.
Para serie:
UPSTYPE dumb DEVICE /dev/ttyS0
/dev/ttyS0 hace referencia al puerto serie #1; ejecutar: dmesg | grep tty te listará los puertos serie de la PC, vos deberás saber en cual lo conectaste (se muestran en orden: 1, 2, 3 y 4).
Cuarta opción: POLLTIME. Tiempo que indica cada cuátos segundos el programa ‘le preugnta’ a la UPS cuál es su estado. 60 es un buen número.
Otras que no modificaremos y dejaremos por default:
LOCKFILE /var/lock
SCRIPTDIR /etc/apcupsd
PWRFAILDIR /etc/apcupsd
NOLOGINDIR /etc
Seguimos: ONBATTERYDELAY indica, en segundos, el tiempo desde que se detecta un evento de falla hasta que se reacciona y se acepta como un verdadero evento de falla (sirve para evitar falsos positivos). 6 segundos está bien.
BATTERYLEVEL indica qué porcentaje de batería debe quedar para que se incie un apagado por batería baja. 10 fue mi elección.
MINUTES indica, en minutos (¿en serio?), el tiempo restante que debe quedar de batería para que se inicie un apagado por batería baja. Es similar a la opción anterior, pero en lugar de ser porcentaje de carga, se trata de minutos restantes. El primero de ambos eventos que se produzca es el que tendrá prioridad. Le puse 10 minutos.
TIMEOUT indica durante cuánto tiempo, en segundos, desde el momento en que se detectó una falla, debe estar corriendo la UPS con batería. Cumplido este tiempo, se incia un apagado. Es útil si se quiere, como es mi caso, mantener la batería cargada para seguir usando la PC en épocas de cortes seguidos. Puse 480 segundos, o sea, 8 minutos (se que mi UPS dura hasta 20 minutos). Si se empla una UPS del tipo ‘dumb’, este parámetro debe ser menor al tiempo que se sabe durará la batería, dado que este tipo de UPS no dan información sobre el estado de la batería. Normalmente, entre 5 y 8 minutos son más que suficientes.
ANNOY indica, en segs, el tiempo en que se ‘molestará’ a los usuarios para que se desconecten, dado que el sistema se apagará. Esta acción se ejecuta los segundos que le hayamos indicado antes que se apage el sistema. 120 segundos.
ANNOYDELAY similar a la anterior, pero el tiempo aquí configurado, en segundos, es el que transcurrirá desde una falla detectada hasta que se ejecute esta acción. 60 segundos
NOLOGON indica si se debe o no permitir que los usuarios se loggeen al sistema cuando está corriendo con baterías. Esto es orientado a un servidor, y no tiene mucho sentido en una PC hogareña. Las opciones posibles son: disable | timeout | percent | minutes | always. Consultar al manual para más info. Yo le puse disable.
KILLDELAY indica, en segs, el tiempo que se tardará, luego de iniciado el apagado, para tratar de apagar la UPS. Se desactiva poniendolo a 0, que es lo que yo hice. Si van a usar esta opción, editen el script killpower. No es necesario con las UPS del tipo USB, dado que las mismas se apagan solas al no detectar carga, en un evento de corte de luz.
Las demás opciones las dejo por default. Guardamos el archivo e iniciamos el servicio: sudo start apcupsd. En caso de que algo falle, simplemente pueden reinciar el equipo.
Listo, ya está configurado. Es hora de hacer pruebas: desconectar el cable, aguardar un tiempo para que nos avise, reconectarlo, desenchufar la ups, etc.
Configurando Scripts
Los scripts ya los tienen, en la sección de descargas. Simplemente deben colocarlos en la carpeta de scripts: /etc/apcupsd; para pegarlos aquí deben ser root: presionen ALT+F2, escriben gksudo nautilus, ingresan la clave y luego pueden extraer y editar comodamente los archivos. Con la consola: sudo cp /ruta/de/origen/* /etc/apcupsd
Si p.e. los extrayeron en el escritorio, seguro les quedó una carpeta apcupsd. Entonces, abrimos un terminal:
cd Escritorio cd apcupsd sudo cp * /etc/apcupsd
Le decimos que sí cuando nos pregunte reemplazar archivos.
Recuerden editar los scripts, donde dice usuario=”hackan” deben poner su usuario; caso contrario no se mostrará la notificación del globo de arriba a la derecha.
Configurando Hibernación
Primero que nada, tu sistema debe tener habilitada hibernación. Para ello, tu partición SWAP debe ser de igual tamaño, o mayor, que tu cantidad de RAM total. Si en el menú de apagado no te aparece la opción de Hibernar, tu sistema no puede hibernar. Puedes solucionarlo fácilmente aumentando el tamaño de la partición SWAP. O buscando una solución en google
Para el caso, lo que debemos hacer es crear un script (archivo de texto) en /usr/local/bin, llamémoslo hibernar o como quieras; puedes usar cualquier editor de texto. Recuerda que debes ser root.
Ejemplo: sudo gedit /usr/local/bin/hibernar
Luego, insertamos lo siguiente (ver en la sección Fuentes la fuente de este script, que fue modificado por mí):
#!/bin/bash
# Hibernate the system - designed to be called via symlink from /etc/apcupsd
# directory in case of apcupsd initiating a shutdown/reboot. Can also be used
# interactively or from any script to cause a hibernate.
#- Config -#
usuario="hackan"
#------------#
case "$1" in
emergency)
echo "Emergency Shutdown. Possible battery failure on UPS ${2}." | wall
# Terminal notify via notify-osd
export DISPLAY=:0 && export XAUTHORITY=/home/${usuario}/.Xauthority && sudo -u ${usuario} /usr/bin/notify-send -i /usr/share/icons/gnome/32x32/status/dialog-error.png "Emergency Shutdown. Possible battery failure on UPS ${2}." 2>&1
;;
*)
echo "UPS ${2} initiated Shutdown Sequence" | wall
# Terminal notify via notify-osd
export DISPLAY=:0 && export XAUTHORITY=/home/${usuario}/.Xauthority && sudo -u ${usuario} /usr/bin/notify-send -i /usr/share/icons/gnome/32x32/status/battery-empty.png "UPS ${2} initiated Shutdown Sequence" 2>&1
;;
esac
# Do the hibernate
/etc/acpi/hibernate.sh
# At this point system should be hibernated - when it comes back, we resume this script here
# On resume, tell controlling script (/etc/apcupsd/apccontrol) NOT to continue with default action (i.e. shutdown).
exit 99
Este script también se encuentra en la descarga junto con los otros.
En un entorno multiusuario, convendría pasarle el nombre de usuario como parámetro, y bueno, editar acorde el resto de los scripts.
Guardar esto, y ahora crearemos vínculos con este script, desde la carpeta de scripts del apcupsd: /etc/apcupsd:
sudo su ln -s /usr/local/bin/hibernar /etc/apcupsd/doreboot ln -s /usr/local/bin/hibernar /etc/apcupsd/doshutdown ln -s /usr/local/bin/hibernar /etc/apcupsd/emergency ln -s /usr/local/bin/hibernar /etc/apcupsd/remotedown ln -s /usr/local/bin/hibernar /etc/apcupsd/restartme exit
Eso es todo
Capturas de pantalla
Las siguientes capturas las hice, como verán, simulando los eventos: es decir, pasándole al script apccontrol el evento que quería simular.
Antes que pregunten, les comento: son screenlets las boludeces del escritorio; es conky el de la derecha; estoy usando nautilus elementary; el tema se llama “A New Hope” (jjm66 creó un post sobre este tema recientemente) y los íconos son Faenza Dark.
Fuentes
> http://ubuntuforums.org/showthread.php?p=4302102
Por la idea de hibernar
> http://www.apcupsd.com/manual/manual.html
Manual de APCUPSD
> http://cweiske.de/tagebuch/DBus%20notify-send%20over%20network.htm
Por la genial solución al problema de notify-send, cuando es ejecutado por otro usuario
> http://www.linuxconfig.org/Bash_scripting_Tutorial
Como siempre lo menciono, un simple tutorial para aprender a escribir scripts.
Palabras finales
Pueden distribuir y/o modificar los scripts y la información como les plazca, son open source
Lo que les pido es que me mencionen en el mismo. Se aceptan sugerencias, corrección de bugs, etc.
Espero que les sea útil. Sin más, me despido.
¡Saludos!
Fue otra creación de HacKan & CuBa co.






Seguime en Twitter 