Cómo monitorizar un SAI Salicru con Raspberry Pi Zero.

En cualquier infraestructura doméstica o profesional, el SAI (Sistema de Alimentación Ininterrumpida) es el guardián silencioso que protege nuestros equipos. Sin embargo, un SAI solo es realmente útil si sabemos exactamente qué está pasando con él en tiempo real.

En este artículo, vamos a configurar un sistema de alertas avanzado utilizando una Raspberry Pi y el software NUT (Network UPS Tools) para convertir un SAI Salicru convencional en un dispositivo inteligente y conectado.

El objetivo es automatizar el control total de nuestra energía mediante un Bot de Telegram que nos mantendrá informados con mensajes detallados y visuales. Al finalizar este tutorial, tu sistema será capaz de:

  • Notificar cortes y restablecimientos de corriente de forma instantánea.
  • Enviar reportes detallados con voltajes de entrada, salida y estado de la batería.
  • Gestionar estados críticos como el nivel de batería bajo o la necesidad de sustitución de celdas (REPLBATT).
  • Proteger tu hardware, avisándote justo antes de que la Raspberry Pi realice un apagado controlado para evitar daños en la tarjeta SD.

Todo esto mediante un script optimizado que garantiza que la información que recibes en tu móvil es veraz y estable, permitiéndote tomar decisiones informadas estés donde estés.


Sistema

Como sistema operativo voy utilizar Rasbperry Pi OS lite 64bits, basado en Debian 13. El usuario del sistema será nut y el host será zero.

Materiales necesarios

Instalación de NUT

Actualizamos la lista de repositorios e instalamos los paquetes oportunos.

sudo apt update && sudo apt install nut nut-client nut-server curl bc -y

Configuración del hardware.

Según el modelo de SAI, nut puede manejar distintos tipos de driver. Antes de configurar el archivo ups.conf conecta el cable USB de la PI al SAI y ejecuta este comando:

sudo nut-scanner -U

Este comando escaneará los buses USB y te dirá exactamente qué driver recomienda NUT para tu dispositivo específico.

nut@zero:~ $ sudo nut-scanner -U
Cannot load SNMP library (libnetsnmp.so.40) : file not found. SNMP search disabled.
Cannot load XML library (libneon.so.27) : file not found. XML search disabled.
Cannot load AVAHI library (libavahi-client.so.3) : file not found. AVAHI search disabled.
Cannot load IPMI library (libfreeipmi.so.17) : file not found. IPMI search disabled.
Scanning USB bus.
[nutdev1]
	driver = "nutdrv_qx"
	port = "auto"
	vendorid = "0665"
	productid = "5161"
	product = "USB to Serial"
	vendor = "Cypress Semiconductor"
	bus = "001"
	device = "002"
	busport = "001"
	###NOTMATCHED-YET###bcdDevice = "0002"

Observa que el driver recomendado es «nutdrv_qx«.

Archivos de configuración de NUT

Define el driver, editando el siguiente archivo.

sudo nano /etc/nut/ups.conf

Al comienzo del archivo, pega lo siguiente.

[salicru]
    driver = nutdrv_qx
    port = auto
    vendorid = 0665
    productid = 5161
    vendor = "Cypress Semiconductor"
    product = "USB to Serial"
    desc = "Salicru SOHO 2000"

En ese mismo archivo busca la línea maxretry = 3 comentala y déjala así.

#maxretry = 3

Guarda con Crtl + o y cierra con Crtl + x

Configura el modo editando el siguiente archivo.

sudo nano /etc/nut/nut.conf 

Busca la línea MODE, cambia la línea a standalone.

MODE=standalone

Configurar el acceso (upsd.conf)

Una vez que el driver está leyendo los datos del USB, necesitamos que el «servidor de NUT» (upsd) recoja esa información y la deje disponible para resto de equipos y otros programas (como nuestro script de Telegram o el comando upsc) puedan consultarla.

Para ello, editamos el archivo de configuración del demonio:

sudo nano /etc/nut/upsd.conf

Este archivo suele tener lineas que apuntan al localhost como las que vemos a continuación.

LISTEN 127.0.0.1 3493
LISTEN ::1 3493

Si las tienes, borralas y deja solo una línea LISTEN tal y como queda en la siguiente instrucción.

LISTEN 0.0.0.0 3493

El 0.0.0.0 sirve para que los demás equipos vean a la Pi Zero.

«Por seguridad, NUT viene configurado para ser ‘tímido’ (127.0.0.1) y solo hablar consigo mismo. Al cambiarlo a 0.0.0.0, convertimos a nuestra Raspberry Pi Zero en un Faro de Energía: ahora cualquier equipo de nuestra red local puede ver el estado del SAI y saber cuándo debe ponerse a salvo.»

¿Qué hace exactamente LISTEN 0.0.0.0?

Cuando configuras LISTEN 0.0.0.0 en el archivo upsd.conf de la Pi Zero, le estás diciendo al servidor NUT: «No te escondas; acepta preguntas de cualquier dirección IP que llegue a esta Raspberry».

  • Sin el 0.0.0.0 (solo con 127.0.0.1): La Pi Zero está «sorda» a lo que venga de fuera. Tus equipos intentarán llamarla por red, pero ella no responderá porque solo escucha sus propios pensamientos internos (localhost).
  • Con el 0.0.0.0: La Pi Zero abre sus «oídos» a toda la red local. Ahora, cuando el i7 pregunte: «¿Cómo va la batería?», la Pi Zero podrá escucharlo y responderle con los datos del Salicru.

¿Cómo «ve» la Pi Zero a los demás?

Curiosamente, la Pi Zero no necesita «ver» activamente a los demás equipos para protegerlos. Funciona al revés:

  1. La Pi Zero (Maestro) simplemente publica la información del SAI en la red.
  2. Los demás equipos (Esclavos como la Pi 5 o el i7) se conectan a ella constantemente para «leer» esa información.
  3. En el momento en que la Pi Zero detecta batería baja, cambia su estado a FSD (Forced Shutdown).
  4. Los esclavos, que están vigilando ese estado cada pocos segundos, ven el cambio y deciden apagarse por su cuenta.

Configurar 0.0.0.0 es como abrir la ventanilla de información de la Pi Zero al resto de la casa. Permite que tus PCs potentes se conviertan en «clientes» que consultan el estado del SAI a través de la red WiFi o Ethernet.

¿127.0.0.1 vs 0.0.0.0? Entendiendo la «Escucha» de Red

Para que tu estrategia de apagado coordinado funcione, es vital entender qué dirección IP debe usar el servidor NUT. Aquí tienes la comparativa de lo que sucede en tu Raspberry Pi Zero:

Configuración (LISTEN)AlcanceSeguridad¿Cuándo usarla?
127.0.0.1 (Localhost)🔒 Solo Interno. La Pi Zero solo se habla a sí misma.Máxima. Nadie fuera de la Pi puede ver los datos.Cuando solo quieres recibir avisos por Telegram desde esa Raspberry.
0.0.0.0 (Todas las IPs)🌍 Toda la Red. La Pi Zero se vuelve visible para el i7, la Pi 5 y el resto de PCs.Media. Requiere usar contraseñas en upsd.users.Obligatorio para apagar otros equipos de casa por red.

Crear la regla de permisos (udev)

La regla de udev es la forma que tiene Linux (en este caso tu Raspberry Pi con Debian) de gestionar los dispositivos que conectas físicamente a los puertos.

Para crear la regla, abre el editor nano con el siguiente comando.

sudo nano /etc/udev/rules.d/99-nut-ups.rules

Pega dentro esta línea exactamente:

SUBSYSTEM=="usb", ATTR{idVendor}=="0665", ATTR{idProduct}=="5161", MODE="0660", GROUP="nut"

(Guarda con Ctrl+O, Enter y sal con Ctrl+X).

Los valores de la regla, los vimos cuando ejecutamos el comando nut-scanner -U de donde extraemos los valores idVendor y idProduct.

Aplicamos la regla con:

sudo udevadm control --reload-rules && sudo udevadm trigger

Como Linux es un sistema multiusuario y seguro, por defecto no permite que cualquier programa (como el software de NUT) «hable» directamente con un hardware USB a menos que seas el administrador (root). La regla de udev que creamos sirve para decirle al sistema: «Cuando veas este SAI de Salicru, dáselo al grupo ‘nut’ para que pueda leer sus datos».

Anatomía de la regla

La línea que pusimos en /etc/udev/rules.d/99-nut-ups.rules se desglosa así:

SUBSYSTEM=="usb", ATTR{idVendor}=="0665", ATTR{idProduct}=="5161", MODE="0660", GROUP="nut"

  • SUBSYSTEM=="usb": Le dice a Linux que solo mire en los puertos USB.
  • ATTR{idVendor}=="0665": «Busca al fabricante 0665».
  • ATTR{idProduct}=="5161": «Y que el producto sea el 5161».
  • MODE="0660": Esto define los permisos de archivos de Linux. 0660 significa que el dueño y el grupo pueden leer y escribir, pero el resto del mundo no puede hacer nada.
  • GROUP="nut": Aquí está la magia. Le asigna la propiedad del puerto al grupo nut. Como el software de monitorización corre bajo el usuario nut, ahora ya tiene «llave» para entrar al puerto USB.

¿Por qué es necesaria en la Raspberry Pi?

Sin esta regla, cuando el driver nutdrv_qx intenta preguntar al SAI «¿cuánta batería te queda?», el sistema operativo le responde: «Acceso denegado».

Si esta regla no está o está mal aplicada, te saldrá el error insufficient permissions. Al añadir la regla, el permiso se vuelve automático: cada vez que arranques la Raspberry o reconectes el USB, Linux aplicará estas instrucciones al instante.

Sincronizar los servicios

Ejecuta esto para limpiar y arrancar de forma oficial:

sudo systemctl stop nut-monitor nut-server
sudo rm -f /run/nut/*.pid
sudo systemctl start nut-server
sudo systemctl start nut-monitor

Comprobar la comunicación

Ahora, espera unos 5 segundos y lanza:

upsc salicru@localhost

El comando nos muestra en tiempo real la información detallada, el estado y las variables del Sistema de Alimentación Ininterrumpida (SAI/UPS)que está gestionado localmente mediante la herramienta NUT (Network UPS Tools)

nut@zero:~ $ upsc salicru@localhost
Init SSL without certificate database
battery.voltage: 27.4
device.type: ups
driver.debug: 0
driver.flag.allow_killpower: 0
driver.name: nutdrv_qx
driver.parameter.pollfreq: 30
driver.parameter.pollinterval: 2
driver.parameter.port: auto
driver.parameter.product: USB to Serial
driver.parameter.productid: 5161
driver.parameter.synchronous: auto
driver.parameter.vendor: Cypress Semiconductor
driver.parameter.vendorid: 0665
driver.state: updateinfo
driver.version: 2.8.1
driver.version.data: Q1 0.08
driver.version.internal: 0.36
driver.version.usb: libusb-1.0.28 (API: 0x100010a)
input.frequency: 49.8
input.voltage: 235.2
input.voltage.fault: 235.2
output.voltage: 231.3
ups.beeper.status: enabled
ups.delay.shutdown: 30
ups.delay.start: 180
ups.load: 0
ups.productid: 5161
ups.status: OL
ups.temperature: 25.0
ups.type: offline / line interactive
ups.vendorid: 0665
nut@zero:~ $

Puerto de escucha

Como dato interesante, comprueba si el puerto 3493 que configuramos anteriormente, está a la escucha

nut@zero:~ $ ss -ltn | grep 3493
LISTEN 0      16           0.0.0.0:3493      0.0.0.0:*  

Las líneas LISTEN, indican que la Raspberry ya tiene la oreja puesta y está lista para informar sobre el estado del Salicru.

Procesos

Puedes escribir upsutil salicru@localhost o simplemente ver el estado del servicio:

Para verificar si el monitor (upsmon) está funcionando correctamente en tu Raspberry Pi, usa estos comandos:

nut@zero:~ $ ps aux | grep upsmon
root        6906  0.0  0.6   7304  2688 ?        Ss   10:05   0:00 /lib/nut/upsmon -F
nut         6907  0.0  1.2  10236  5120 ?        S    10:05   0:03 /lib/nut/upsmon -F
nut         9598  0.0  0.4   8804  2064 pts/0    S+   21:39   0:00 grep --color=auto upsmon
nut@zero:~ $ 

Deberías ver 3 procesos: uno que corre como root (el que tiene permiso para apagar la Pi) el otro como el usuario nut y el otro es simplemente el comando que acabamos de escribir.

Comprobar el estado del servicio.

Ejecuta el comando sudo systemctl status nut-monitor

nut@zero:~ $ sudo systemctl status nut-monitor
● nut-monitor.service - Network UPS Tools - power device monitor and shutdown controller
     Loaded: loaded (/usr/lib/systemd/system/nut-monitor.service; enabled; preset: enabled)
     Active: active (running) since Sat 2026-03-07 22:12:57 CET; 12h ago
 Invocation: 95d0260bee1c4eca9ad4a618365a8a2c
    Process: 1091 ExecStartPre=/usr/bin/systemd-tmpfiles --create /usr/lib/tmpfiles.d/nut-common-tmpfiles.conf (code=exited, status=0/SUCCESS)
   Main PID: 1093 (upsmon)
      Tasks: 2 (limit: 176)
        CPU: 3.333s
     CGroup: /system.slice/nut-monitor.service
             ├─1093 /lib/nut/upsmon -F
             └─1098 /lib/nut/upsmon -F

mar 07 22:12:57 zero systemd[1]: Starting nut-monitor.service - Network UPS Tools - power device monitor and shutdown controller...
mar 07 22:12:57 zero systemd[1]: Started nut-monitor.service - Network UPS Tools - power device monitor and shutdown controller.
mar 07 22:12:57 zero nut-monitor[1093]: fopen /run/nut/upsmon.pid: No such file or directory
mar 07 22:12:57 zero nut-monitor[1093]: Could not find PID file to see if previous upsmon instance is already running!
mar 07 22:12:57 zero nut-monitor[1093]: UPS: salicru@localhost (primary) (power value 1)
mar 07 22:12:57 zero nut-monitor[1093]: Using power down flag file /etc/killpower
mar 07 22:12:57 zero nut-monitor[1098]: Init SSL without certificate database
mar 07 22:12:57 zero nut-monitor[1098]: upsnotify: notify about state 2 with libsystemd: was requested, but not running as a service unit now, will not spam more about it
mar 07 22:12:57 zero nut-monitor[1098]: upsnotify: failed to notify about state 2: no notification tech defined, will not spam more about it
mar 07 22:12:57 zero nut-monitor[1098]: upsnotify: logged the systemd watchdog situation once, will not spam more about it
nut@zero:~ $ 

Si aparece en verde (active (running)), el vigilante está despierto.

Configurando los avisos por terminal.

sudo nano /etc/nut/upsmon.conf

Pega el siguiente texto debajo

# Banderas para ejecutar el comando (EXEC)
NOTIFYFLAG ONLINE   SYSLOG+WALL+EXEC
NOTIFYFLAG ONBATT   SYSLOG+WALL+EXEC
NOTIFYFLAG LOWBATT  SYSLOG+WALL+EXEC
NOTIFYFLAG SHUTDOWN SYSLOG+WALL+EXEC
NOTIFYFLAG REPLBATT SYSLOG+WALL+EXEC

Reinicia el servicio con:

sudo systemctl stop nut-monitor nut-server

Esto dará avisos en la terminal de tu raspberry, pero no lo hará si estas accediendo por ssh.

Cómo configurar el apagado automático (upsmon)

Como nuestra Raspberry Pi Zero 2W está conectada al Salicru, vamos a configurar el sistema para que se apague de forma segura.

Configurar el usuario

Debemos de tener un par de usuarios configurados para la gestión del SAI, que será el usurario administrador [monuser] y el usuario de los equipos remotos que será [remotemon]

Edita el archivo de usuarios de NUT:

sudo nano /etc/nut/upsd.users

Añade esto al final:

[monuser]
    password = mi_password_segura
    upsmon master

Si quieres, puedes dar a [monuser] privilegios de administrador así:

[monuser]
    password = mi_password_segura
    upsmon master
    actions = SET
    instcmds = ALL

Para dar privilegios de administrador a un usuario, tan solo agrégale las directrices actions e instcmds

Para el usuario remoto, añade este perfil al final (usa una contraseña distinta a la de admin):

[remotemon]
    password = clave_red_segura
    upsmon slave

Configurar el monitor

Edita el archivo del monitor:

sudo nano /etc/nut/upsmon.conf

Busca la sección MONITOR y asegúrate de que quede así:

MONITOR salicru@localhost 1 monuser mi_password_segura master
SHUTDOWNCMD "/sbin/shutdown -h now"
POWERDOWNFLAG /etc/killpower

Activar el servicio

Reinicia todo para que los cambios tengan efecto:

sudo systemctl restart nut-monitor

¿Qué pasará ahora cuando se corte la luz?

Si el SAI se apaga antes de que la Raspberry complete su apagado, podrías tener el mismo problema que con un corte normal de luz, archivos corruptos en la MicroSD. Este sistema está diseñado con una secuencia de retardo muy específica para evitar esto, El Retardo (Delay). Cuando la Raspberry envía la orden de «Kill Power», no le está diciendo al SAI «Apágate ya», sino «Apágate dentro de X segundos».

Si te fijas en los datos de tu upsc salicru@localhost, hay una línea clave:

ups.delay.shutdown: 30

Esto significa que cuando la Raspberry envía la orden final, el SAI Salicru inicia una cuenta atrás interna de 30 segundos.

La Secuencia Cronológica

Para que veas que es seguro, este es el orden real de los eventos:

  1. Raspberry detecta Batería Baja: Inicia su propio proceso de apagado (SHUTDOWNCMD).
  2. Cierre de Servicios: Debian detiene bases de datos, logs y procesos. La tarjeta SD deja de escribir datos.
  3. Script Final de NUT: Justo en el último segundo del apagado (cuando el sistema ya está en modo «solo lectura»), se ejecuta la orden de «Kill Power» hacia el SAI.
  4. SAI recibe la orden: El Salicru empieza su cuenta atrás de 30 segundos.
  5. Raspberry muere: La Pi termina de apagarse por completo en 2 o 3 segundos más.
  6. El SAI se apaga: 27 segundos después de que la Pi ya esté totalmente «muerta», el SAI corta la energía.

¿Por qué es necesario que el SAI se apague?

Imagina que no enviamos el «Kill Power»:

  • La Raspberry se apaga y se queda esperando.
  • El SAI se queda encendido con batería hasta que se agote al 0%.
  • Vuelve la luz de la calle.
  • Problema: Como el SAI nunca llegó a cortarle la corriente a la Raspberry (porque se quedó en un estado de «espera» con la batería agotada pero sin apagar el circuito), la Raspberry no detectará que ha vuelto la energía y no arrancará sola. Se quedará apagada hasta que alguien vaya físicamente a desenchufarla y enchufarla.

Resumen de seguridad

Con el valor de 30 segundos que tiene tu Salicru de fábrica:

  • La Raspberry tiene tiempo de sobra (le sobran unos 25 segundos) para terminar de cerrarlo todo antes de que el SAI corte el flujo eléctrico.
  • Es un método estándar y muy seguro.

Un detalle importante: En las Raspberry Pi, para que el ciclo de «vuelva la luz y se encienda sola» funcione perfecto, asegúrate de que el SAI esté configurado para rearmarse automáticamente (cosa que los Salicru SOHO+ hacen por defecto).

Para estar seguro de que la Raspberry sabe que es la jefa del apagado (modo master), ejecuta:

upsc salicru@localhost ups.delay.shutdown

Si te responde 30, significa que todo está listo para que, en caso de emergencia, la Pi le ordene al Salicru esperar 30 segundos antes de cortar la energía, dándole tiempo a la MicroSD para cerrarse a salvo.


¿Cómo saber si realmente se apagará? (Simulación segura)

Si quieres estar 100% seguro de que la configuración es correcta sin apagar la Raspberry de golpe, puedes mirar el log del sistema:

sudo journalctl -f -u nut-monitor -u nut-server

Si ahora mismo desenchufas el SAI de la pared, Verás en el log UPS salicru@localhost on battery.

nut@zero:~ $ sudo journalctl -f -u nut-monitor -u nut-server
mar 07 18:05:06 zero nut-server[7408]: Instant command: upsmon@::1 did test.battery.start.quick on salicru (tracking ID: disabled)
mar 07 18:05:06 zero upsd[7408]: Instant command: upsmon@::1 did test.battery.start.quick on salicru (tracking ID: disabled)
mar 07 19:24:09 zero nut-server[7408]: Instant command: upsmon@::1 did test.battery.start.quick on salicru (tracking ID: disabled)
mar 07 19:24:09 zero upsd[7408]: Instant command: upsmon@::1 did test.battery.start.quick on salicru (tracking ID: disabled)
mar 07 19:27:08 zero nut-server[7408]: Instant command: upsmon@::1 did test.battery.start.quick on salicru (tracking ID: disabled)
mar 07 19:27:08 zero upsd[7408]: Instant command: upsmon@::1 did test.battery.start.quick on salicru (tracking ID: disabled)
mar 07 20:05:29 zero nut-monitor[6907]: UPS salicru@localhost on battery
mar 07 20:05:45 zero nut-monitor[9348]: Network UPS Tools upsmon 2.8.1

Si miras en upsc salicru@localhost verás que cambia a status: OB.

nut@zero:~ $ upsc salicru@localhost
Init SSL without certificate database
battery.voltage: 26.9
device.type: ups
driver.debug: 0
driver.flag.allow_killpower: 0
driver.name: nutdrv_qx
driver.parameter.pollfreq: 30
driver.parameter.pollinterval: 2
driver.parameter.port: auto
driver.parameter.product: USB to Serial
driver.parameter.productid: 5161
driver.parameter.synchronous: auto
driver.parameter.vendor: Cypress Semiconductor
driver.parameter.vendorid: 0665
driver.state: quiet
driver.version: 2.8.1
driver.version.data: Q1 0.08
driver.version.internal: 0.36
driver.version.usb: libusb-1.0.28 (API: 0x100010a)
input.frequency: 50.0
input.voltage: 9.6
input.voltage.fault: 9.6
output.voltage: 227.4
ups.beeper.status: enabled
ups.delay.shutdown: 30
ups.delay.start: 180
ups.load: 0
ups.productid: 5161
ups.status: OB
ups.temperature: 25.0
ups.type: offline / line interactive
ups.vendorid: 0665

Lo más importante:

Como el modelo SOHO+ 2000, tiene mucha autonomía para una Raspberry Pi Zero 2W (que consume casi nada). No esperes a que llegue a Low Battery (batería baja) de forma real porque podría tardar horas.

Si en algún momento quieres probar que el apagado funciona de verdad, el comando es:

sudo upsmon -c fsd

(Esto significa «Forced Shutdown» y simula que la batería se ha agotado, iniciando el proceso de apagado de seguridad inmediatamente).

¡Ya está todo listo y protegido! Tu Raspberry Pi ahora sobrevivirá a los cortes de luz sin corromper la tarjeta SD.

El script de alertas para Telegram

Creamos el script que enviará los mensajes:

sudo nano /usr/local/bin/nut-telegram.sh

Copia y pega el siguiente script. No olvides reemplazar «tu_token» y «tu_id» por los tuyos propios

#!/bin/bash

# Configuración del Bot de Telegram
TOKEN="tu_token"
CHAT_ID="tu_id"
export LC_ALL=C

# Función interna para leer los sensores (Lógica estable)
capturar() {
    BATERIA_V=$(upsc salicru@localhost battery.voltage 2>/dev/null || echo "0.0")
    VOLTAJE_IN=$(upsc salicru@localhost input.voltage 2>/dev/null || echo "0.0")
    VOLTAJE_OUT=$(upsc salicru@localhost output.voltage 2>/dev/null || echo "0.0")
    CARGA_SAI=$(upsc salicru@localhost ups.load 2>/dev/null || echo "0")
    ESTADO_SAI=$(upsc salicru@localhost ups.status 2>/dev/null || echo "N/A")
}

case "$1" in
    *"on battery"*)
        ICONO="🚨"
        TITULO="CORTE DE SUMINISTRO"
        
        # BUCLE DE ESPERA: No envía hasta que la entrada sea < 50V real
        intentos=0
        capturar
        while [[ "${VOLTAJE_IN%.*}" -gt 50 ]] && [[ $intentos -lt 12 ]]; do
            sleep 5
            capturar
            ((intentos++))
        done

        # --- DIAGNÓSTICO DE SALUD AL CORTE ---
        V_INT=${BATERIA_V%.*}
        if [ "$V_INT" -lt 24 ]; then
            DETALLE="¡OJO! Las baterías están muy bajas ($BATERIA_V V). Salud crítica, considera cambiarlas."
        else
            DETALLE="El SAI está operando con baterías. Salud química OK ($BATERIA_V V)."
        fi
        ;;

    *"on line power"*)
        ICONO="✅"
        TITULO="CORRIENTE RESTABLECIDA"
        DETALLE="El sistema vuelve a la red eléctrica."

        # BUCLE DE ESPERA: No envía hasta que la entrada sea > 200V real
        intentos=0
        capturar
        while [[ "${VOLTAJE_IN%.*}" -lt 200 ]] && [[ $intentos -lt 12 ]]; do
            sleep 5
            capturar
            ((intentos++))
        done
        ;;

    *"low battery"*)
        ICONO="⚠️"
        TITULO="BATERIA CRITICA"
        DETALLE="Nivel muy bajo. El apagado es inminente."
        capturar
        ;;

    *"SHUTDOWN"*)
        ICONO="💀"
        TITULO="APAGADO DE EMERGENCIA"
        DETALLE="La Raspberry se apaga para proteger la SD."
        capturar
        ;;

    *"REPLBATT"*)
        ICONO="🛠️"
        TITULO="FALLO DE BATERIA"
        DETALLE="Es necesario sustituir las baterías del Salicru."
        capturar
        ;;

    *)
        ICONO="ℹ️"
        TITULO="NOTIFICACION SAI"
        DETALLE="$1"
        capturar
        ;;
esac

# Mensaje final con los iconos: 🔌 y ⚡
CUERPO="$ICONO *$TITULO* $ICONO
------------------------------------
📝 $DETALLE

🔋 *Bateria:* $BATERIA_V V
🔌 *Entrada:* $VOLTAJE_IN V
⚡ *Salida:* $VOLTAJE_OUT V
📊 *Carga SAI:* $CARGA_SAI%
📈 *Estado:* $ESTADO_SAI"

# Envío a Telegram
curl -s -X POST "https://api.telegram.org/bot$TOKEN/sendMessage" \
     --data-urlencode "chat_id=$CHAT_ID" \
     --data-urlencode "text=$CUERPO" \
     --data-urlencode "parse_mode=Markdown" > /dev/null 2>&1

Importante: Dale permisos de ejecución con:

sudo chmod 755 /usr/local/bin/nut-telegram.sh

y haz que el dueño sea el usuario de nut:

sudo chown nut:nut /usr/local/bin/nut-telegram.sh

Configurando los avisos por telegram

Volvemos a configurar las flags para los avisos por telegram, por lo que volvemos a entrar al archivo upsmon.conf

 sudo nano /etc/nut/upsmon.conf

Copia encima o debajo de las anteriores notificaciones

# Comando externo para notificaciones
NOTIFYCMD "/usr/local/bin/nut-telegram.sh"

# Definición de mensajes que activan el script
NOTIFYMSG ONLINE    "UPS salicru@localhost on line power"
NOTIFYMSG ONBATT    "UPS salicru@localhost on battery"
NOTIFYMSG LOWBATT   "UPS salicru@localhost low battery"
NOTIFYMSG SHUTDOWN  "SHUTDOWN"
NOTIFYMSG REPLBATT  "REPLBATT"

Reinicia el servicio

sudo systemctl restart nut-monitor

Haz una prueba manual con:

sudo -u nut /usr/local/bin/nut-telegram.sh "Prueba manual"

Test

Podemos listar los comandos que puede realizar nuestro salicru.

nut@zero:~ $ upscmd -l salicru
Instant commands supported on UPS [salicru]:

beeper.toggle - Toggle the UPS beeper
driver.killpower - Tell the driver daemon to initiate UPS shutdown; should be unlocked with driver.flag.allow_killpower option or variable setting
driver.reload - Reload running driver configuration from the file system (only works for changes in some options)
driver.reload-or-error - Reload running driver configuration from the file system (only works for changes in some options); return an error if something changed and could not be applied live (so the caller can restart it with new options)
driver.reload-or-exit - Reload running driver configuration from the file system (only works for changes in some options); exit the running driver if something changed and could not be applied live (so service management framework can restart it with new options)
load.off - Turn off the load immediately
load.on - Turn on the load immediately
shutdown.return - Turn off the load and return when power is back
shutdown.stayoff - Turn off the load and remain off
shutdown.stop - Stop a shutdown in progress
test.battery.start - Start a battery test
test.battery.start.deep - Start a deep battery test
test.battery.start.quick - Start a quick battery test
test.battery.stop - Stop the battery test

De la lista podemos ejecutar test.battery.start.quick que lo único que hace es pasar al estado OL CAL y hacer un test del sistema para el chequeo interno del SAI pero no hará como su nombre indica, ningún test de las baterías.

nut@zero:~ $ upscmd -u upsmon -p tu_contresña_segura salicru test.battery.start.quick
OK

Mientras se realiza el test, puedes comprobar el voltage de la batería en tiempo real con este comando, que se mantendrá inmutable ya que el el sistema se mantiene todo el tiempo OnLine.

while true; do upsc salicru@localhost battery.voltage; sleep 1; done

Mantenimiento Preventivo Mensual

«Investigando a fondo con la consola de NUT, descubrimos que el Salicru SOHO+ protege sus baterías. Aunque veas comandos como test.battery.start.deep, el SAI los ignora para evitar descargas innecesarias. El único comando que acepta es el quick, que activa el modo OL CAL (Calibración Online). Este modo es genial para verificar que los relés y el inversor funcionan, pero no estresa la batería.

Conclusión: Para saber la salud real de tus baterías en este modelo, el ‘Test del Tirón’ (desenchufar 10 segundos) sigue siendo el único modo. Mi script de Telegram te avisará al instante de cuánto cae el voltaje en ese momento y en que estado se encuentran las baterías.»

Si el driver nutdrv_qx solo nos permite el OL CAL, vamos a convertir ese «estiramiento» en nuestro test mensual. Aunque no descargue la batería, es vital porque obliga a los relés físicos a moverse. Un SAI que nunca hace un test puede acabar con los relés «pegados» por el calor y el desuso, y el día que se vaya la luz de verdad, no conmutará.

Script de «Mantenimiento Preventivo de Relés e Inversor».

Abre una terminal y ejecuta el siguiente comando para crear nuestro archivo de mantenimiento

sudo nano /usr/local/bin/mantenimiento-sai.sh

Pega el siguente texto, no olvides de introducir «tu_token_de_telegram» «tu_id_de_chat» y «tu_contraseña_segura»

#!/bin/bash

# --- CONFIGURACIÓN ---
TOKEN="TU_TOKEN_DE_TELEGRAM"
ID="TU_ID_DE_CHAT"
UPS="salicru"
USUARIO="upsmon"
CLAVE="tu_contraseña_segura"

# 1. Inicio del mantenimiento
curl -s -X POST "https://api.telegram.org/bot$TOKEN/sendMessage" -d "chat_id=$ID&text=⚙️ *Mantenimiento Mensual:* Iniciando test de relés en $UPS..."

# 2. Lanzar el Quick Test (Modo CAL)
upscmd -u $USUARIO -p $CLAVE $UPS test.battery.start.quick > /dev/null
sleep 2

# 3. Verificamos si el SAI ha entrado en modo calibración
STATUS=$(upsc $UPS ups.status)

if [[ "$STATUS" == *"CAL"* ]]; then
    # Esperamos a que termine (vimos que dura unos 9-10 seg)
    sleep 10
    FINAL_STATUS=$(upsc $UPS ups.status)
    if [[ "$FINAL_STATUS" == "OL" ]]; then
        MSG="✅ *TEST OK*: Los relés han conmutado y el inversor ha arrancado correctamente. El sistema de emergencia está operativo."
    else
        MSG="⚠️ *AVISO*: El test ha terminado pero el estado es $FINAL_STATUS. Revisar manualmente."
    fi
else
    MSG="❌ *ERROR*: El SAI ha ignorado la orden de test. Es posible que necesite un reinicio del servicio NUT."
fi

# 4. Enviar resultado
curl -s -X POST "https://api.telegram.org/bot$TOKEN/sendMessage" -d "chat_id=$ID&parse_mode=Markdown&text=$MSG"

Este script hará el test aceptado por el Salicru, verificará que el estado pase por OL CAL y te informará de que la electrónica de conmutación sigue viva.

La automatización (Cron)

Para que se haga solo una vez al mes (por ejemplo, el día 1 a las 10:00), añade esto a tu sudo crontab -e:

00 10 1 * * /usr/local/bin/mantenimiento-sai.sh

«¿Por qué automatizar un test que no descarga la batería?»

Muchos usuarios cometen el error de no tocar su SAI hasta que se va la luz. El problema es que los relés son piezas mecánicas que pueden fallar por falta de uso. Mi script mensual fuerza al Salicru a entrar en modo OL CAL. Aunque no descargue la batería, este proceso hace que los relés ‘hagan ejercicio’ y que el inversor se autochequee. Es la garantía de que, cuando llegue el apagón real, la parte mecánica del SAI no estará agarrotada.

Tabla de Salud de la Batería (Sistema de 24V)

«Una vez que recibas la notificación en tu móvil, ¿cómo saber si esos voltios son buenos o malos? He preparado esta tabla de referencia para que sepas cuándo es el momento de sacar la cartera y comprar repuestos:»

Voltaje en BateríaEstado de SaludSignificado TécnicoAcción
> 27.0 VExcelenteCarga completa en flotación.Ninguna.
24.5 V – 26.5 VNormalFuncionamiento correcto bajo carga.Uso habitual.
23.5 V – 24.4 V⚠️ Aviso / DébilLa batería empieza a perder capacidad química.Planificar cambio a medio plazo.
< 23.5 V🚨 CríticoAgotamiento inminente o celdas dañadas.Cambio urgente. Riesgo de apagón repentino.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Scroll al inicio