"Después del juego es antes del juego"
Sepp Herberger

Mostrando entradas con la etiqueta sai. Mostrar todas las entradas
Mostrando entradas con la etiqueta sai. Mostrar todas las entradas

jueves, 11 de junio de 2026

Monitorización de SAI Phasak SIRIUS 1560VA con nut

Bueno, nos han mandado SAI nuevos para reemplazar los que van fallando. En concreto ahora nos toca un Phasak SIRIUS 1560VA. Una vez instalado físicamente nos toca configurar el nut para monitorizarlo de forma correcta. Enchufo el cable USB al PC donde tengo la monitorización (el servidor del centro) y a ver que sale:
# lsusb
Bus 002 Device 026: ID 1a86:7523 QinHeng Electronics CH340 serial converter
Es raro, se identifica como un puerto Serie-USB. Este tipo de dispositivos se manejan con el dispositivo /dev/ttyUSBx. El problema es que cada vez que lo enchufas, desenchufas o pasa algo con la conexión el número final cambia, por lo que no podemos saber si será ttyUSB0, ttyUSB1, ttyUSB2.... Vamos a arreglar eso haciendo que siempre tenga un nombre fijo:
# nano /etc/udev/rules.d/99-ups.rules
Con contenido:
SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", SYMLINK+="ttyUPS_phasak"
Ahora siempre se llamará /dev/ttyUPS_phasak. Vamos a aplicar los cambios:
# udevadm control --reload-rules
# udevadm trigger
Siguiente paso: dar permisos al usuario nut para acceder a /dev/ttyUPS_phasak.
# usermod -aG dialout nut
Con esto ya podemos añadir el dispositivo a la configuración de nut en /etc/nut/ups.conf (Internet me ha recomendado usar el driver blazer_ser):
...
[phasak]
driver = blazer_ser
port = /dev/ttyUPS_phasak
desc = "UPS Phasak"
....
Vamos a reiniciar todo para que se apliquen los cambios:
# upsdrvctl stop
# upsdrvctl start
# systemctl restart nut-server
Y vamos a ver si se establece la conexión:
# upsc phasak
Init SSL without certificate database
battery.charge: 100
battery.voltage: 27.10
battery.voltage.high: 26.00
battery.voltage.low: 20.80
battery.voltage.nominal: 24.0
device.type: ups
driver.name: blazer_ser
driver.parameter.pollinterval: 2
driver.parameter.port: /dev/ttyUSB0
driver.parameter.synchronous: auto
driver.version: 2.8.0
driver.version.internal: 1.58
input.current.nominal: 6.0
input.frequency: 50.0
input.frequency.nominal: 50
input.voltage: 235.0
input.voltage.fault: 0.0
input.voltage.nominal: 230
output.voltage: 235.0
ups.beeper.status: enabled
ups.delay.shutdown: 30
ups.delay.start: 180
ups.load: 9
ups.status: OL
ups.temperature: 25.0
ups.type: offline / line interactive
Yeah, funciona! Ahora solo falta añadir al fichero /etc/nut/upsmon.conf el identificador del SAI para poder monitorizarlo:
MONITOR phasak@localhost 1 admin pontupassword primary
El resto de la configuración del NUT, su cliente y sus alertas está requeteexplicada en otras entradas pasadas del blog, puedes empezar por esta entrada.

Nos vemos!

miércoles, 5 de marzo de 2025

Monitorización del SAI con nut en Debian 12.

Ya hemos tratado varias veces en el pasado de este blog el tema de la monitorización del SAI del servidor desde Debian. Vamos a hacer ahora una recopilación de todo lo aplicado otras veces montado sobre Debian 12, que es el sistema que usamos a día de hoy. Vamos allá.

SAI que tenemos: un Salicru SPS One, que conectado por USB se detecta así:
# lsusb
...
Bus 002 Device 004: ID 0665:5161 Cypress Semiconductor USB to Serial
...
Paquetes a instalar:
# apt-get install nut-client nut-server nut-cgi
Antes de empezar la configuración se aconseja tener un servidor de correo activo para poder enviar los mensajes de cambio de estado del SAI. En el Apartado 2 de esta entrada del blog cuento como montar el sistema que mejor me ha funcionado: postfix reenviando los correos a través de una cuenta de gmail.com

Vamos ahora a ver los distintos ficheros de configuración. El primero es ups.conf, que tiene los datos para conecar al SAI. Una buena manera de saber que ponemos aquí es usar la salida del comando "nut-scanner".
# cat /etc/nut/ups.conf
maxretry = 3
[salicru]
driver = "nutdrv_qx"
port = "auto"
vendorid = "0665"
productid = "5161"
product = "HID UPS"
serial = ""
vendor = "HID UPS"
Los otros ficheros quedarían:
# cat /etc/nut/upsd.conf 
LISTEN 127.0.0.1
LISTEN 172.1.1.2 # PONER LA IP de la maquina donde se ejecuta la monitorización
LISTEN 0.0.0.0 3493
# cat /etc/nut/upsd.users
[admin]
password = mipasswordfavorita
actions = set
actions = fsd
instcmds = ALL
upsmon primary
# cat /etc/nut/hosts.conf 
MONITOR salicru@localhost "SAI Salicru Servidor"
# cat /etc/nut/nut.conf
MODE=standalone
# cat /etc/nut/upsmon.conf 
RUN_AS_USER nut
MONITOR salicru@localhost 1 admin mipasswordfavorita primary
MINSUPPLIES 1
SHUTDOWNCMD "/usr/local/bin/apagar_servidores.sh"
NOTIFYCMD "/sbin/upssched"
NOTIFYMSG ONLINE "UPS: Normal state"
NOTIFYMSG ONBATT "UPS: On battery"
NOTIFYMSG LOWBATT "UPS: Battery low"
NOTIFYMSG FSD "UPS: Starting shutdown"
NOTIFYMSG COMMOK "UPS: Communication restored"
NOTIFYMSG COMMBAD "UPS: Communication lose"
NOTIFYMSG SHUTDOWN "UPS: Shutting down"
NOTIFYMSG NOCOMM "UPS: No communication"
NOTIFYMSG REPLBATT "UPS: Replace battery"
NOTIFYFLAG ONLINE SYSLOG+WALL+EXEC
NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC
NOTIFYFLAG LOWBATT SYSLOG+WALL+EXEC
NOTIFYFLAG FSD SYSLOG+WALL+EXEC
NOTIFYFLAG COMMOK SYSLOG+WALL+EXEC
NOTIFYFLAG COMMBAD SYSLOG+WALL+EXEC
NOTIFYFLAG SHUTDOWN SYSLOG+WALL+EXEC
NOTIFYFLAG NOCOMM SYSLOG+WALL+EXEC
NOTIFYFLAG REPLBATT SYSLOG+WALL+EXEC
POLLFREQ 5
POLLFREQALERT 5
HOSTSYNC 15
DEADTIME 15
POWERDOWNFLAG /etc/killpower
RBWARNTIME 43200
NOCOMMWARNTIME 300
FINALDELAY 5
# cat /etc/nut/upsset.conf 
# Network UPS Tools - upsset.conf sample file
#
# This file is provided to ensure that you do not expose your upsd server
# to the world upon installing the CGI programs.  Specifically, it keeps
# the upsset.cgi program from running until you have assured it that you
# have secured your web server's CGI directory.
#
# By default, your web server will probably let anyone access upsset.cgi
# once it is installed.  This means that anyone could attempt to crack
# upsd logins since they would appear to be coming from your web server,
# rather than the outside world, slipping through any ACL/ACCESS definitions.
#
# For this reason, you *MUST* first secure your CGI programs before
# enabling upsset in this configuration file.  If you can't do this in
# your web server, then you should *not* run this program.
#
# For Apache, the .htaccess file can be used in the directory with the
# programs.  You'll need something like this:
#
#   <Files upsset.cgi>
#       deny from all
#       allow from your.network.addresses
#   </Files>
#
# You will probably have to set "AllowOverride Limit" for this directory in
# your server-level configuration file as well.
#
# If this doesn't make sense, then stop reading and leave this program alone.
#
# Assuming you have all this done (and it works), then you may uncomment
# the line below and start using upsset.cgi through your web browser.
#
###
I_HAVE_SECURED_MY_CGI_DIRECTORY
###
# cat /etc/nut/upssched.conf
CMDSCRIPT  /usr/local/bin/avisoups.sh
PIPEFN /tmp/upssched.pipe
LOCKFN /tmp/upssched.lock
AT ONBATT * START-TIMER  ups-on-battery-shutdown  600
AT ONLINE * CANCEL-TIMER  ups-on-battery-shutdown
AT ONBATT * START-TIMER ups-on-battery 5
AT ONLINE * CANCEL-TIMER ups-on-battery
AT ONLINE * EXECUTE ups-back-on-line
AT REPLBATT * EXECUTE ups-change_battery
AT LOWBATT * EXECUTE ups-low-battery
AT COMMOK * EXECUTE ups-comunication-ok
AT COMMBAD * EXECUTE ups-comunication-bad
AT NOCOMM * EXECUTE ups-nocomm
AT FSD * EXECUTE ups-fsd
AT SHUTDOWN * EXECUTE ups-shutdown
Para probar que funciona podemos reiniciar los servicios e intentar conectar manualmente con SAI a ver si nos da los datos de carga, voltaje y demás:
# service nut-server restart
# service nut-monitor restart
# upsc salicru
Init SSL without certificate database
battery.charge: 100
battery.voltage: 27.10
battery.voltage.high: 26.00
battery.voltage.low: 20.80
battery.voltage.nominal: 24.0
device.type: ups
driver.name: nutdrv_qx
driver.parameter.pollfreq: 30
driver.parameter.pollinterval: 2
driver.parameter.port: auto
driver.parameter.product: HID UPS
driver.parameter.productid: 5161
driver.parameter.serial: 
driver.parameter.synchronous: auto
driver.parameter.vendor: HID UPS
driver.parameter.vendorid: 0665
driver.version: 2.8.0
driver.version.data: Mustek 0.07
driver.version.internal: 0.32
driver.version.usb: libusb-1.0.26 (API: 0x1000109)
input.current.nominal: 6.0
input.frequency: 50.1
input.frequency.nominal: 50
input.voltage: 232.7
input.voltage.fault: 232.7
input.voltage.nominal: 230
output.voltage: 234.8
ups.beeper.status: enabled
ups.delay.shutdown: 30
ups.delay.start: 180
ups.load: 10
ups.productid: 5161
ups.status: OL
ups.type: offline / line interactive
ups.vendorid: 0665
Con lo anterior se ha instalado un interface web al que podemos acceder en la URL: "http://ip-maquina/cgi-bin/nut/upsstats.cgi?host=salicru@localhost". De los diferentes ficheros .cgi que permiten gestionar vía web el SAI me gusta dejar, por temas de seguridad, el fichero "upsset.cgi" sin permisos:
 ls -l /usr/lib/cgi-bin/nut/
total 140
-rwxr-xr-x 1 root root 45416 ene 25  2023 upsimage.cgi
-rwx------ 1 root root 43336 ene 25  2023 upsset.cgi
-rwxr-xr-x 1 root root 47456 ene 25  2023 upsstats.cgi
Ahora muestro los scripts que uso para manejar los eventos y comunicarlos al servidor:
# cat /usr/local/bin/apagar_servidores.sh
#!/bin/bash
# Ejecutado desde  upsmon.conf cuando se la la orden de apagado de servidores.

function mailSend() {

   echo "$2" | mail -s "$1" -a "From: Avisos.ies <tu.correo@gmail.com>"  tu.correo@educarex.es

}

FECHA=$(date)
estado=$(upsc salicru ups.status 2> /dev/null)
en_bateria=$(echo $estado | tr ' ' '\n' | grep "OB")

if [ -z $en_bateria ]  #Si en up.status no parece OB, no estamos en bateria. Es un SHUTDOWNCMD innecesario
then
   MESSAGE_MAIL="Evento SHUTDOWNCMD pero estado $estado. No apagamos el servidor"
   mailSend  "$FECHA => $MESSAGE_MAIL"  "[UPS] Evento SHUTDOWNCMD"
   echo "$FECHA => SAI: $MESSAGE_MAIL" >> /var/log/sai.log  # /var/log/sai.log permisos 644 y nut:nut
else
   MESSAGE_MAIL="Apagado servidor por evento SHUTDOWNCMD"
   mailSend  "$FECHA => $MESSAGE_MAIL"  "[UPS] Evento SHUTDOWNCMD"
   echo "$FECHA => SAI: $MESSAGE_MAIL" >> /var/log/sai.log  # /var/log/sai.log permisos 644 y nut:nut
   ssh root@tercero "/sbin/shutdown -h +0"
   sleep 10
   /sbin/shutdown -h +0
fi

exit 0
# cat /usr/local/bin/avisoups.sh
#!/bin/bash

function mailSend() {

   echo "$2" | mail -s "$1" -a "From: Avisos.ies <tu.correo@gmail.com>"  tu.correo@educarex.es

}

MESSAGE_MAIL=""
EVENT_TYPE=$1
APAGADO=0
FECHA=$(date)

case "$EVENT_TYPE" in
    "ups-on-battery-shutdown")
        MESSAGE_MAIL="UPS on battery: shutdown now"
        APAGADO=1
        ;;
    "ups-on-battery")
        MESSAGE_MAIL="UPS on battery: warning"
        ;;
    "ups-comunication-bad")
        MESSAGE_MAIL="Communications with UPS lost"
        ;;
    "ups-change_battery")
        MESSAGE_MAIL="UPS battery needs to be replaced"
        ;;
    "ups-back-on-line")
        MESSAGE_MAIL="UPS on line power"
        ;;
    "ups-low-battery")
        MESSAGE_MAIL="UPS battery is low"
        ;;
    "ups-comunication-ok")
        MESSAGE_MAIL="Communications with UPS established"
        ;;
    "ups-nocomm")
        MESSAGE_MAIL="No communication with UPS"
        ;;
    "ups-fsd")
        MESSAGE_MAIL="UPS FSD: forced shutdown received"
        APAGADO=1
        ;;
    "ups-shutdown")
        MESSAGE_MAIL="UPS shutdown: shutdown received"
        APAGADO=1
        ;;
esac

mailSend  "$FECHA => $MESSAGE_MAIL"  "[UPS] Event $EVENT_TYPE de SAI Virgen de Guadalupe:"
echo "$FECHA => SAI: $MESSAGE_MAIL" >> /var/log/sai.log

if [ $APAGADO = "1" ]
then
    sleep 30
    /usr/local/bin/apagar_servidores.sh
fi
Por último, si tenemos monit podemos controlar que los servicios están levantados:
# cat /etc/monit/conf.d/monitrc.nut
check process nut-monitor with pidfile /var/run/nut/upsmon.pid
   group nut
   start program = "/bin/systemctl start nut-monitor.service"
   stop  program = "/bin/systemctl stop nut-monitor.service"
   if not exist then restart
   if 5 restarts within 5 cycles then timeout

check process nut-server matching "/lib/nut/upsd"
   group nut  
   start program = "/bin/systemctl start nut-server.service"
   stop  program = "/bin/systemctl stop nut-server.service"
   if not exist then restart
   if 5 restarts within 5 cycles then timeout
Y con esto lo tenemos ya, el porqué de todas las cosas que se configuran en estos ficheros está explicado en los anteriores artículos dedicados a nut en este blog. Espero que este sea la entrada definitiva.

sábado, 12 de mayo de 2018

Monitorizando nuestro SAI con nut (Parte 4)

Hace ya tiempo que no dedico una entrada al SAI, pero como se me estropeó el que tenía y recibí uno de reemplazo, al conectarlo y monitorizarlo de nuevo he aprovechado para probar y cerrar temas pendientes. Las entradas precedentes eran:


En el apartado 5 de la última entrada dejaba abierto el problema del apagado del servidor cuando está funcionando con baterías, un tema peliagudo que no tenía muy probado por falta de tiempo y oportunidad. No es plan desconectar el SAI de la corriente y ver que pasa en horario de producción. Ahora si he probado con calma y estas son las conclusiones.

1. Ficheros de configuración básica.

Empecemos repasando como tenemos los ficheros básicos en /etc/nut:

/etc/nut/hosts.conf
MONITOR salicru@localhost "UPS Virgen de Guadalupe"
/etc/nut/nut.conf
MODE=standalone
/etc/nut/ups.conf
maxretry = 3
[salicru]
driver = blazer_usb
port = auto
subdriver = cypress
protocol = mustek
desc = "SAI Salicru"
vendorid = 0665
productid = 5161
bus = "004" # adaptalo a tu caso 
/etc/nut/upsd.conf
LISTEN 127.0.0.1 3493
#IP del servidor donde esta conectado el SAI con el cable USB.
LISTEN 172.20.123.2 3493
/etc/nut/upsd.users
[admin_sai]
password = 13578axd
upsmon master
/etc/nut/upsset.conf
deny from all
allow from 172.20.123.0  
/etc/nut/upsmon.conf
MONITOR salicru@localhost 1 admin_sai 13578axd master
RUN_AS_USER nut
MINSUPPLIES 1
SHUTDOWNCMD "/root/scripts/apagar_servidores.sh"
POLLFREQ 5
POLLFREQALERT 5
HOSTSYNC 15
DEADTIME 15
POWERDOWNFLAG /etc/killpower
RBWARNTIME 43200
NOCOMMWARNTIME 300
FINALDELAY 5
NOTIFYCMD "/sbin/upssched"
NOTIFYMSG ONLINE "UPS: Normal state"
NOTIFYMSG ONBATT "UPS: On battery"
NOTIFYMSG LOWBATT "UPS: Battery low"
NOTIFYMSG FSD "UPS: Starting shutdown"
NOTIFYMSG COMMOK "UPS: Communication restored"
NOTIFYMSG COMMBAD "UPS: Communication lose"
NOTIFYMSG SHUTDOWN "UPS: Shutting down"
NOTIFYMSG REPLBATT "UPS: Replace battery"
NOTIFYMSG NOCOMM      "UPS %s is unavailable"
NOTIFYMSG NOPARENT    "upsmon parent process died - shutdown impossible"
NOTIFYFLAG ONLINE SYSLOG+WALL+EXEC
NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC
NOTIFYFLAG LOWBATT SYSLOG+WALL+EXEC
NOTIFYFLAG FSD SYSLOG+WALL+EXEC
NOTIFYFLAG COMMOK SYSLOG+WALL+EXEC
NOTIFYFLAG COMMBAD SYSLOG+WALL+EXEC
NOTIFYFLAG SHUTDOWN SYSLOG+WALL+EXEC
NOTIFYFLAG REPLBATT SYSLOG+WALL+EXEC
NOTIFYFLAG NOCOMM     SYSLOG+WALL+EXEC
NOTIFYFLAG NOPARENT   SYSLOG+WALL+EXEC
/etc/nut/upssched.conf:
CMDSCRIPT /usr/bin/upssched-cmd
PIPEFN /tmp/upssched.pipe
LOCKFN /tmp/upssched.lock
AT ONBATT * START-TIMER ups-on-battery 15
AT ONLINE * CANCEL-TIMER ups-on-battery
AT ONLINE * EXECUTE ups-back-on-line
AT REPLBATT * EXECUTE ups-change-battery  
AT LOWBATT * EXECUTE ups-low-battery  
AT FSD * EXECUTE ups-fsd
AT SHUTDOWN * EXECUTE ups-shutdown
AT COMMOK * EXECUTE ups-comunication-ok 
AT COMMBAD * EXECUTE ups-comunication-bad
Of course, en todo lo anterior pondremos el usuario que nos apetezca (en lugar de admin_sai), contraseña y direccionamiento IP correspondiente. Los que he puesto yo son de pega.

2. Proceso de apagado desde nut.

Con calma he leído todo lo que he encontrado sobre el proceso de eventos que genera NUT cuando el SAI está funcionando con batería y empieza a descargarse. Repasamos la secuencia de eventos:

  • El SAI está operando con corriente y con los 2 leds de la derecha del frontal encendidos. Se va la corriente eléctrica y se activa la batería del SAI. De los 6 leds que tiene se encienden en verde los 5 de la derecha, a modo de indicador de carga máxima y comienza a sonar un beep cada pocos segundos. Se irán apagando conforme se descargue la bateria y el beep sonará cada vez con mayor cadencia.
  • Si miramos el estado del SAI con "upsc salicru ups.status" vemos que está en "OB", On Battery. El demonio ups-monitor ha enviado el evento ONBATT para que lo procese el ups-scheduler.
  • Pasa el tiempo y la batería se va descargando. Con "upsc salicru battery.charge" podemos ver el % de carga.
  • Algunos SAI tienen un parámetro battery.charge.low que permite definir el umbral de carga mínima de la batería. Ese umbral se puede redefinir poniendo "override.battery.charge.low = 25" en /etc/nut/ups.conf, pero nuestro Salicru no lo tiene y el umbral está fijado en el 10%. Podemos poner dicho parámetro, reiniciar el demonio y ver con "upsc salicru" que battery.charge.low = 25, pero a la hora de la verdad dicho valor es ignorado y todo se comporta como ese 10% estuviese escrito en piedra.
  • En general: la forma de determinar si la batería está baja depende el SAI/driver concreto y se calcula en función de battery.charge/battery.charge.low y battery.runtime/battery.runtime.low.
  • Pasado el umbral de batería baja se genera un evento LOWBATT para que lo procese el ups-scheduler. Aquí empieza la fiesta.
  • Si nuestro nut tiene esclavos (como vimos en la entrada anterior del blog), se les notifica un evento FSD (forced shutdown). A su vez, cada esclavo:
    • Genera un evento SHUTDOWN.
    • Espera FINALDELAY segundos(tipicamente 5).
    • Ejecuta su propio SHUTDOWNCMD.
    • Desconecta del upsd maestro.
  • El nut maestro, si ha enviado el FSD a los esclavos espera HOSTSYNC segundos (típicamente 15) para darles tiempo a desconectar. Pasado esto se envía un FSD a si mísmo, lo cual:
    • Genera un evento SHUTDOWN.
    • Espera FINALDELAY segundos(tipicamente 5).
    • Crea el fichero POWERDOWNFLAG - usualmente /etc/killpower.
    • Ejecuta su propio SHUTDOWNCMD.
  • A diferencia del resto de código, el comando SHUTDOWNCMD se ejecuta con permisos de root. Esto es debido a que siempre hay en marcha dos instancias de upsmon, una con el usuario "nut" y otra con el usuario "root". Está última está casi siempre ociosa y solo existe para ejecutar lo que diga el parámetro SHUTDOWNCMD definido en upsmon.conf.
Esta es la teoría, haciendo una prueba en entorno real vamos a describir lo que pasa en la práctica:
  • Tengo conectado al SAI una fuente del servidor principal, un servidor auxiliar y un monitor. Desconecto el SAI de la corriente.
  • El parámetro ups.status se pone en OB. battery.charge baja rápidamente en menos de un minuto del 100% al 85-88%. Esto pinta mal.
  • Se estabiliza y empieza a bajar despacio, con los leds frontales apagándose conforme avanza la carga. Este es el ritmo:

    HORA CARGA STATUS EVENTO
    16:40 100% OL
    16:41 100% OB ONBATT
    16:42 88% OB
    17:09 69% OB
    17:24 65% OB
    17:42 29% OB
    17:45:11 15% OB
    17:45:25 12% OB
    17:45:51 10% OB LB FSD LOWBAT, FSD
    17:45:56 4% OB LB FSD EJECUCIÓN SHUTDOWNCMD
    17:46:11 0% OB LB FSD
    17:46:26 42% OL FSD VUELVE LA CORRIENTE
    ONLINE

    Para hacer el cuadrante anterior he capturado los datos con este script:
    #!/bin/bash
    
    while true
    do
       hora=$(date)
       carga=$(upsc salicru battery.charge 2> /dev/null)
       estado=$(upsc salicru ups.status  2> /dev/null)
       voltio=$(upsc salicru battery.voltage  2> /dev/null)
       echo "$hora -> ${carga}% $estado $voltio" >> /root/sai-status.txt
       echo "$hora -> ${carga}% $estado $voltio"
       sleep 15
    done
    
  • Conclusiones:
    • Hay una descarga rapidísima al comienzo, de un 12% en cuestión de segundos.
    • Luego va bajando con suavidad durante una hora. A los 30 minutos está al 70%. A los 60 llega al 15%.
    • Cuando llega al 15% empieza a bajar de nuevo en caída libre y en 2 minutos llega al 0%.
    • Al bajar del 10% se generan los eventos LOWBATT y FSD. Pocos segundos después se llama a SHUTDOWNCMD con credenciales de root.
    • Con la batería al 0% no se corta la corriente, pero no he querido tentar cuanto aguanta así hasta el apagado físico real.
    • Al conectar de nuevo el SAI a la corriente vuelve a cargar y el estado OB se transforma en OL, pero se queda activado el flag FSD ya que no ha llegado a suceder el apagado del servidor.

En resumen: el SAI aguanta 60 minutos o más con 2 servidores y un monitor, pero tiene una curva de descarga bastante acelerada al comienzo y al final. Desde que se genera el evento LOWBATT hasta que se llega al 0% de carga pasan segundos, lo que queda muy poco tiempo de maniobra si queremos apagar varias máquinas.

Una segunda cosa a que destacar que el SAI queda en estado "FSD OL" al volver la corriente en el último momento. Para quitar el flag FSD sin reiniciar el servidor hay que reiniciar el demonio nut-server, pero al hacer eso algunas veces (no siempre) se genera un evento FSD y se ejecuta un SHUTDOWCMD. Esto puede provocar que si no tenemos precauciones con lo que se hace en SHUTDOWNCMD se apague el servidor estando el SAI ya con corriente externa.

En general, siempre que llegamos al estado FSD (incluso manualmente haciendo "/sbin/upsmon -c fsd") tarde o temprano se ejecutará SHUTDOWNCMD, por lo que es algo que habrá que tener en cuenta.

En el siguiente apartado veremos como he abordado las cuestiones planteadas.

3. Configuración del apagado.

Ya que los pocos segundos que transcurren desde que se genera el LOWBATT+FSD hasta que la batería llega al 0% no me inspiran ninguna confianza lo que voy a hacer es que cuando se lleven 30 minutos de batería (momento en que está está sobre el 70%) se apague el servidor de forma segura.

Podría forzar más tiempo, pero si en media hora no ha vuelto la corriente parece que la cosa va para largo y... ¿para que esperar lo inevitable?

Modificamos /etc/nut/upssched.conf para incluir un nuevo timer de 1800 segundos:
CMDSCRIPT /usr/bin/upssched-cmd
PIPEFN /tmp/upssched.pipe
LOCKFN /tmp/upssched.lock
AT ONBATT * START-TIMER  ups-on-battery-shutdown 1800
AT ONLINE * CANCEL-TIMER  ups-on-battery-shutdown
AT ONBATT * START-TIMER ups-on-battery 15
AT ONLINE * CANCEL-TIMER ups-on-battery
AT ONLINE * EXECUTE ups-back-on-line
AT REPLBATT * EXECUTE ups-change-battery  
AT LOWBATT * EXECUTE ups-low-battery  
AT FSD * EXECUTE ups-fsd
AT SHUTDOWN * EXECUTE ups-shutdown
AT COMMOK * EXECUTE ups-comunication-ok 
AT COMMBAD * EXECUTE ups-comunication-bad
Los eventos son gestionados con /usr/bin/upssched-cmd:
#! /bin/bash
#
# This script should be called by upssched via the CMDSCRIPT directive.
# 
# Here is a quick example to show how to handle a bunch of possible
# timer names with the help of the case structure.
#
# This script may be replaced with another program without harm.
#
# The first argument passed to your CMDSCRIPT is the name of the timer
# from your AT lines.

function mailSend() {

   echo "$2" | mail -s "$1" -a "From: Avisos.ies "  tu.correo@gmail.com

}

MESSAGE_MAIL=""
EVENT_TYPE=$1
APAGADO=0
FECHA=$(date)

case "$EVENT_TYPE" in
    "ups-on-battery-shutdown")
      #Saltado evento AT ONBATT * START-TIMER  ups-on-battery-shutdown 1800: llevamos 30 minutos con bateria. Apagamos.
      MESSAGE_MAIL="UPS on battery: shutdown now"
      APAGADO=1
    ;;
    "ups-on-battery")
      MESSAGE_MAIL="UPS on battery: warning"
    ;;
    "ups-comunication-bad")
      MESSAGE_MAIL="Communications with UPS lost"
    ;;
    "ups-change-battery")
      MESSAGE_MAIL="UPS battery needs to be replaced"
    ;;
    "ups-back-on-line")
      MESSAGE_MAIL="UPS on line power"
    ;;
    "ups-low-battery")
      MESSAGE_MAIL="UPS battery is low"
    ;;
    "ups-comunication-ok")
      MESSAGE_MAIL="Communications with UPS established"
    ;;
    "ups-shutdown")  # Llega tras el FSD
      MESSAGE_MAIL="FSD: shutdown message"
    ;;
    *)
      MESSAGE_MAIL="Aviso tipo: $EVENT_TYPE"
    ;;
esac

mailSend  "$FECHA => $MESSAGE_MAIL"  "[UPS] Event $EVENT_TYPE de SAI Virgen de Guadalupe:"
echo "$FECHA => SAI: $MESSAGE_MAIL" >> /var/log/sai.log  # /var/log/sai.log permisos 664 y root:nut

if [ $APAGADO = "1" ]
then
    sleep 30
    /sbin/upsmon -c fsd #  Esto genera un evento ups-fsd y un evento ups-shutdown, que a su vez llama a SHUTDOWNCMD como root.
fi
La mayoría de los eventos mandan un correo y escriben en el log /var/log/sai.log. Tan sólo es difrente el salto del timer ups-on-battery-shutdown lanza una orden "/sbin/upsmon -c fsd", que genera a su vez un evento FSD y posteriormente dispara la ejecución de SHUTDOWNCMD, que apunta a /root/scripts/apagar_servidores.sh:
#!/bin/bash

function mailSend() {

   echo "$2" | mail -s "$1" -a "From: Avisos.ies "  tu.correo@gmail.com

}

FECHA=$(date)
estado=$(upsc salicru ups.status 2> /dev/null)
en_bateria=$(echo $estado | tr ' ' '\n' | grep "OB")

if [ -z $en_bateria ]  #Si en up.status no parece OB, no estamos en bateria. Es un SHUTDOWNCMD innecesario
then
   MESSAGE_MAIL="Evento SHUTDOWNCMD pero estado $estado. No apagamos el servidor"
   mailSend  "$FECHA => $MESSAGE_MAIL"  "[UPS] Evento SHUTDOWNCMD"
   echo "$FECHA => SAI: $MESSAGE_MAIL" >> /var/log/sai.log  # /var/log/sai.log permisos 664 y root:nut
else
   MESSAGE_MAIL="Apagado servidor por evento SHUTDOWNCMD"
   mailSend  "$FECHA => $MESSAGE_MAIL"  "[UPS] Evento SHUTDOWNCMD"
   echo "$FECHA => SAI: $MESSAGE_MAIL" >> /var/log/sai.log  # /var/log/sai.log permisos 664 y root:nut
   ssh root@servidor-auxiliar "/sbin/shutdown -h +0"
   sleep 10
   /sbin/shutdown -h +0
fi
exit 0
El script anterior recordemos que se ejecuta como root.

Primero comprueba que el SAI sigue en estado OB (en bateria). Si no es así, manda un mensaje diciendo que aunque se haya recibido un FSD-SHUTDOWN no se apagará nada. Esto previene que si tenemos el flag FSD activado estando OL (ON LINE, con corriente) se apague el servidor accidentalmente al reiniciar el demonio nut-server.

Si el SAI está en estado OB se mandan mensajes, se apaga un servidor auxiliar (con el que tenemos una relación de confianza para ejecutar comandos por ssh en él) y finalmente se apaga el servidor que ejecuta nut. Todo esto se hace a la media hora de estar funcionando con el SAI, por lo que da tiempo a cerrar todo tranquilamente ya que queda mas de la mitad de la batería.

4. Fuentes.

Acabo haciendo honores a las fuentes que he seguido para redactar esta entrada:

Y con esto creo que quedo cerrado del todo el tema de nut mientras que no suceda nada excepcional.

Nos leemos pronto.