Files
ROMFASTSQL/proxmox/cluster/ups/docs/UPS-MONTHLY-TEST.md
Marius 0b8e8f6892 fix(ups): testul lunar de baterie nu putea da alarma niciodata
Verdictul se calcula din CHARGE_DROP, dar la acest UPS battery.charge nu e o
masuratoare independenta: driverul nutdrv_qx / Voltronic-QS-Hex o deduce liniar
din tensiune intre battery.voltage.low (20.8V) si .high (26.0V). Verificat pe
toate probele din 11 luni: 25.76V -> 95.4% -> raportat 95%.

Traduse in tensiune, pragurile vechi cereau o cadere de 3.70V pentru FAIR (primul
prag care trimite severity warning) si 4.74V pentru POOR, intr-un test de 40 de
secunde. Maximul observat in 11 luni a fost 2.59V. De asta raportul a iesit
EXCELLENT 11 luni la rand si ar fi facut-o si cu bateria pe moarte.

Evaluarea se face acum pe tendinta: mediana ultimelor 3 rulari fata de mediana
primelor 6, plus o plasa de siguranta pe tensiune absoluta (<25.0V forteaza FAIR,
<24.0V forteaza POOR). Fereastra de 3 impiedica o luna atipica sa declanseze
singura alarma - verificat pe feb 2026 (2.59V), care nu bascuelaza verdictul.

Istoricul se tine in /var/log/ups-battery-trend.csv, populat cu cele 14 rulari
extrase din jurnal (2025-10-06 -> 2026-08-01), ca linia de baza sa fie valida
imediat si nu peste 9 luni.

Starea la zi: baza 1.82V, recent 2.12V, raport 1.16x -> EXCELLENT. Cresterea de
~16% in 10 luni e reala dar sub banda de avertizare; FAIR s-ar da la 2.73V.

Instalat pe pvemini in /opt/scripts/, verificat cap-coada cu testul de baterie
anulat, ca sa nu descarce bateria: tendinta calculata corect, template-urile
regenerate cu campurile noi, notificarea PVE::Notify trimisa cu succes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RRyaDj39hPQ89SZS6URRpS
2026-08-27 14:46:35 +03:00

540 lines
15 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Test Lunar Automat Baterie UPS
## Despre
Script automat pentru testarea lunară a bateriei UPS care rulează pe data de 1 a fiecărei luni la ora 00:00. Testul verifică capacitatea reală a bateriei prin comutare pe baterie și monitorizare descărcare/recuperare.
## Funcționalitate
### Ce face scriptul:
1. **Verificare status UPS** înainte de test
- Battery charge, voltage
- Input/output voltage
- Load %
- Verifică că UPS este Online
2. **Rulare test baterie automat**
- Comandă: `upscmd nutdev1 test.battery.start.quick`
- UPS comută pe baterie pentru ~10 secunde
- Descarcă efectiv bateria pentru testare reală
3. **Monitorizare în timp real** (30 secunde)
- Status UPS
- Battery charge %
- Battery voltage
- Detectare anomalii
4. **Analiză rezultate**
- Calculează scăderea încărcării (%)
- Calculează scăderea tensiunii (V)
- Evaluează sănătatea bateriei
5. **Monitorizare recuperare** (5 minute)
- Urmărește reîncărcarea bateriei
- Calculează rata de recuperare
- Oprește când bateria > 95%
6. **Generare rapoarte**
- Raport HTML detaliat cu grafice
- Raport text pentru email
- Log detaliat în `/var/log/ups-monthly-test.log`
7. **Notificare email**
- Trimite raport prin sistemul de notificări Proxmox
- Include sănătatea bateriei în subject
- Rapoarte salvate în `/tmp/ups-test-YYYYMM/`
## Evaluare Sănătate Baterie
**Evaluarea se face pe tendință, nu pe praguri absolute.** Din 2026-08-27; înainte
se folosea scăderea încărcării față de praguri fixe, care nu funcționa — vezi
[De ce s-a schimbat metoda](#de-ce-sa-schimbat-metoda) mai jos.
### Metoda
Se măsoară **căderea de tensiune sub sarcină** în cele ~40 de secunde de test și se
compară cu linia de bază a acestei baterii:
- **linia de bază** = mediana primelor 6 rulări înregistrate, adică bateria în cea
mai bună stare pe care o avem măsurată;
- **valoarea recentă** = mediana ultimelor 3 rulări, ca o lună atipică (frig,
sarcină mare) să nu declanșeze singură o alarmă;
- **raportul** dintre ele urcă pe măsură ce crește rezistența internă a bateriei,
ceea ce dă avertisment cu luni înainte de cedare.
| Raport față de bază | Sănătate | Severitate email | Acțiune |
|---------------------|----------|------------------|---------|
| < 1.25x | **EXCELLENT** | info | Nicio acțiune |
| 1.25 – 1.50x | **GOOD** | info | Uzură normală, urmărește lunar |
| 1.50 – 2.00x | **FAIR** | ⚠️ warning | Planifică înlocuirea în 3-6 luni |
| ≥ 2.00x | **POOR** | 🔴 error | **URGENT: înlocuiește bateria** |
Peste asta există o **plasă de siguranță pe tensiune absolută**, pentru cazul în
care bateria cedează brusc, înainte să apuce mediana să urce:
| Minim atins în test | Efect |
|---------------------|-------|
| < 25.0 V | forțează cel puțin **FAIR** |
| < 24.0 V | forțează **POOR** direct |
Până se strâng 9 rulări (6 pentru bază + 3 pentru fereastra recentă), verdictul
este **BASELINE** — se colectează date, severitate `info`.
### Fișierul de tendință
`/var/log/ups-battery-trend.csv`, câte o linie per rulare:
```
date,voltage_drop,min_voltage,charge_drop,before_load,after_load,duration
2026-08-01,2.12,25.76,5,10,12,40
```
Se poate reconstrui oricând din jurnal cu
`/opt/scripts/ups-battery-trend-backfill.sh --force`. A fost populat inițial cu
14 rulări extrase din `/var/log/ups-monthly-test.log` (2025-10-06 → 2026-08-01),
ca linia de bază să fie validă imediat și nu peste 9 luni.
### Starea la 2026-08-27
| Perioadă | Cădere de tensiune |
|----------|--------------------|
| oct–dec 2025 (linia de bază) | 1.41 – 2.00 V, mediană **1.82 V** |
| iun–aug 2026 (recent) | 2.12 – 2.23 V, mediană **2.12 V** |
Raport **1.16x** → **EXCELLENT**. Creșterea de ~16% în 10 luni e reală, dar sub
banda de avertizare. Alarma (FAIR) s-ar da la o cădere de ~2.73 V.
### De ce s-a schimbat metoda
`battery.charge` **nu e o măsurătoare independentă** la acest UPS. Driverul
`nutdrv_qx` / `Voltronic-QS-Hex` nu are contor de coulombi; deduce încărcarea
liniar din tensiune, între `battery.voltage.low` (20.8 V) și `battery.voltage.high`
(26.0 V):
```
charge = (V - 20.8) / (26.0 - 20.8) * 100
```
Verificat pe toate probele din 11 luni: 25.76 V → 95.4% → raportat 95%;
25.29 V → 86.3% → raportat 86%. Se potrivește exact de fiecare dată.
Pragurile vechi, traduse înapoi în tensiune, cereau:
| Prag vechi | Însemna cădere de | Observat în 11 luni |
|------------|-------------------|---------------------|
| GOOD (drop 15%) | 2.66 V | maxim 2.59 V |
| FAIR (drop 35%) | **3.70 V** | niciodată |
| POOR (drop 55%) | **4.74 V** | niciodată |
EXCELLENT și GOOD sunt amândouă severitate `info`, deci primul prag care chiar
trimite un avertisment era FAIR, la o cădere de 3.70 V într-un test de 40 de
secunde. O baterie ajunsă acolo e practic un rezistor. De asta testul a raportat
**EXCELLENT 11 luni la rând** și ar fi făcut-o și cu bateria pe moarte.
## Instalare
### 1. Copiere script pe server
```bash
scp scripts/ups-monthly-test.sh root@10.0.20.201:/opt/scripts/
ssh root@10.0.20.201 "chmod +x /opt/scripts/ups-monthly-test.sh"
```
### 2. Configurare cron
Script-ul se adaugă automat în cron la instalare, dar poți verifica:
```bash
ssh root@10.0.20.201 "crontab -l | grep ups-monthly-test"
```
Ar trebui să vezi:
```
# UPS Monthly Battery Test - Rulează pe 1 ale lunii la 00:00
0 0 1 * * /opt/scripts/ups-monthly-test.sh
```
### 3. Test manual (recomandat înainte de prima rulare lunară)
```bash
ssh root@10.0.20.201 "/opt/scripts/ups-monthly-test.sh"
```
**ATENȚIE:** Testul va comuta UPS-ul pe baterie pentru ~10 secunde!
## Configurare
### Parametri editabili în script:
```bash
UPS_NAME="nutdev1" # Numele UPS-ului din NUT
UPS_USER="admin" # Username pentru comenzi NUT
UPS_PASS="parola99" # Parola pentru comenzi NUT
MAIL_TO="root@pam" # Destinatar email rapoarte
```
### Personalizare cron:
Pentru a schimba data/ora de rulare, editează cron:
```bash
ssh root@10.0.20.201
crontab -e
```
Exemple:
```bash
# Rulează pe 1 ale lunii la 02:00 (noapte)
0 2 1 * * /opt/scripts/ups-monthly-test.sh
# Rulează în fiecare Duminică la 00:00 (săptămânal)
0 0 * * 0 /opt/scripts/ups-monthly-test.sh
# Rulează pe 15 ale lunii la 00:00 (mijloc de lună)
0 0 15 * * /opt/scripts/ups-monthly-test.sh
```
## Rapoarte Generate
### 1. Raport HTML
**Locație:** `/tmp/ups-test-YYYYMM/ups-test-report.html`
Conține:
- Header cu data, UPS, nod
- Status sănătate baterie (color-coded)
- Metrici în grid layout:
- Încărcare înainte/după
- Tensiune înainte/după
- Scădere încărcare
- Recuperare în 5 min
- Tabel detalii tehnice
- Recomandări bazate pe sănătate
- Footer cu timestamp și paths
### 2. Raport Text
**Locație:** `/tmp/ups-test-YYYYMM/ups-test-report.txt`
Versiune text simplă pentru email.
### 3. Log Detaliat
**Locație:** `/var/log/ups-monthly-test.log`
Log complet cu toate măsurătorile:
- Timestamp pentru fiecare pas
- Status UPS în timp real
- Toate valorile măsurate
- Erori sau warnings
**Păstrare:** Log-ul este append-only, conține istoric complet al tuturor testelor.
## Logs și Monitorizare
### Vizualizare log în timp real:
```bash
ssh root@10.0.20.201 "tail -f /var/log/ups-monthly-test.log"
```
### Verificare ultimul test:
```bash
ssh root@10.0.20.201 "tail -50 /var/log/ups-monthly-test.log"
```
### Căutare teste anterioare:
```bash
# Caută toate testele din 2025
ssh root@10.0.20.201 "grep 'UPS MONTHLY BATTERY TEST - START' /var/log/ups-monthly-test.log | grep 2025"
# Vezi rezultatul ultimului test
ssh root@10.0.20.201 "grep 'Sănătate baterie:' /var/log/ups-monthly-test.log | tail -1"
```
### Verificare cron execution:
```bash
# Verifică că cron a rulat scriptul
ssh root@10.0.20.201 "grep ups-monthly-test /var/log/syslog"
```
## Email Notifications
### Configurare sistem de mail
Scriptul încearcă să trimită email prin:
1. **mail command** (recomandat)
2. **logger** (fallback - doar în syslog)
#### Instalare mail command (dacă nu există):
```bash
ssh root@10.0.20.201 "apt update && apt install -y mailutils"
```
#### Configurare SMTP pentru Proxmox:
Editează `/etc/postfix/main.cf`:
```bash
relayhost = smtp.gmail.com:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_security_level = encrypt
```
Creează `/etc/postfix/sasl_passwd`:
```
smtp.gmail.com:587 your-email@gmail.com:your-app-password
```
Apoi:
```bash
postmap /etc/postfix/sasl_passwd
chmod 600 /etc/postfix/sasl_passwd*
systemctl restart postfix
```
#### Test email:
```bash
echo "Test email from UPS monitoring" | mail -s "Test" root@pam
```
### Verificare email trimis:
```bash
# Verifică mail queue
ssh root@10.0.20.201 "mailq"
# Verifică mail logs
ssh root@10.0.20.201 "grep 'UPS' /var/log/mail.log"
```
## Troubleshooting
### Testul nu pornește
**Verificare:**
```bash
# UPS online?
upsc nutdev1 ups.status
# Comenzi disponibile?
upscmd -l nutdev1 | grep battery
# Autentificare corectă?
upscmd -u admin -p parola99 nutdev1 test.battery.start.quick
```
### Bateria nu se descarcă în test
**Cauze posibile:**
- UPS-ul nu suportă test real (unele modele low-end)
- Test prea scurt pentru a fi detectat
- Baterie foarte sănătoasă (scădere < 1%)
**Verificare:**
```bash
# Monitorizează tensiune în loc de charge
watch -n 1 'upsc nutdev1 battery.voltage'
# Apoi rulează test manual și observă scăderea
upscmd -u admin -p parola99 nutdev1 test.battery.start.quick
```
### Email nu ajunge
**Verificări:**
```bash
# Mail command instalat?
which mail
# Postfix rulează?
systemctl status postfix
# Verifică logs
tail -50 /var/log/mail.log
# Test manual
echo "Test" | mail -s "Test Subject" root@pam
```
### Script blochează sau timeout
**Cauze:**
- Testul baterie durează prea mult
- UPS nu răspunde
- Probleme rețea
**Soluție:**
Editează scriptul și reduce timeout-urile:
```bash
# Reduce monitorizare de la 15 la 5 iterații
for i in {1..5}; do
```
## Întreținere
### Lunar (După Rulare Automată)
```bash
# Verifică că testul a rulat
ssh root@10.0.20.201 "tail -100 /var/log/ups-monthly-test.log | grep 'COMPLETE'"
# Vezi rezultatul
ssh root@10.0.20.201 "grep 'Sănătate baterie' /var/log/ups-monthly-test.log | tail -1"
# Verifică raportul HTML
ssh root@10.0.20.201 "ls -lh /tmp/ups-test-*/ups-test-report.html"
```
### Anual
```bash
# Cleanup rapoarte vechi (> 12 luni)
ssh root@10.0.20.201 "find /tmp/ups-test-* -type d -mtime +365 -exec rm -rf {} +"
# Rotare log dacă devine prea mare (> 100MB)
ssh root@10.0.20.201 "
if [ \$(stat -f%z /var/log/ups-monthly-test.log) -gt 104857600 ]; then
mv /var/log/ups-monthly-test.log /var/log/ups-monthly-test.log.old
gzip /var/log/ups-monthly-test.log.old
fi
"
```
### La Înlocuire Baterie
După înlocuirea bateriei UPS:
```bash
# Rulează test manual pentru baseline
ssh root@10.0.20.201 "/opt/scripts/ups-monthly-test.sh"
# Verifică că rezultatul este EXCELLENT
ssh root@10.0.20.201 "tail -20 /var/log/ups-monthly-test.log"
# Notează data înlocuirii în log
ssh root@10.0.20.201 "echo '[$(date)] Baterie UPS înlocuită - baseline test executat' >> /var/log/ups-monthly-test.log"
```
## Interpretare Rezultate
### Exemplu rezultat bun:
```
Sănătate baterie: EXCELLENT
Scădere încărcare: 5%
Scădere tensiune: 1.64V
Recuperare: 5% în 30 secunde
```
**Interpretare:** Baterie în stare excelentă, poate susține sarcina, se reîncarcă rapid.
### Exemplu rezultat acceptabil:
```
Sănătate baterie: FAIR
Scădere încărcare: 35%
Scădere tensiune: 4.2V
Recuperare: 15% în 120 secunde
```
**Interpretare:** Baterie uzată, planifică înlocuire în 3-6 luni.
### Exemplu rezultat critic:
```
Sănătate baterie: POOR
Scădere încărcare: 65%
Scădere tensiune: 8.5V
Recuperare: 25% în 300 secunde
```
**Interpretare:** **URGENT!** Baterie critică, înlocuiește imediat! Risc mare de shutdown neplanificat.
## Recomandări Baterie
### Când să înlocuiești bateria:
| Indicator | Bun | Acceptabil | Critic |
|-----------|-----|------------|--------|
| **Vârstă baterie** | < 2 ani | 2-4 ani | > 4 ani |
| **Raport față de linia de bază** | < 1.25x | 1.25-2.0x | > 2.0x |
| **Tensiune minimă în test** | > 25.0V | 24.0-25.0V | < 24.0V |
| **Timp recuperare** | < 1 min | 1-5 min | > 5 min |
| **Teste failed** | 0 | 1-2 | > 3 |
Scăderea încărcării nu mai e criteriu — la acest UPS e tensiunea rescalată, nu o
măsurătoare separată.
### Factori care afectează durata de viață:
- **Temperatură:** Ideal 20-25°C (fiecare +10°C reduce durata cu 50%)
- **Cicluri descărcare:** < 20 cicluri/an = bun
- **Profunzime descărcare:** Descărcări până la 50% = OK, sub 20% = deteriorare
- **Calitate baterie:** Baterii branded (APC, Eaton) vs. generice
## Automatizare Avansată
### Alertare automată când bateria devine POOR:
Adaugă în script (după evaluarea sănătății):
```bash
if [ "$BATTERY_HEALTH" == "POOR" ]; then
# Trimite alert urgent
echo "URGENT: Bateria UPS necesită înlocuire!" | \
mail -s "🔴 ALERT UPS: Baterie CRITICĂ!" admin@company.com
# Notificare SMS (dacă ai configurat)
curl -X POST "https://api.service.com/sms" \
-d "to=+40xxxxxxxxx&message=ALERT: Baterie UPS critica!"
fi
```
### Integrare cu Prometheus/Grafana:
Exportă metrici pentru monitorizare long-term:
```bash
# La final de script, exportă metrici
cat >> /var/lib/node_exporter/textfile_collector/ups_battery.prom << EOF
# HELP ups_battery_health Battery health score (0-100)
# TYPE ups_battery_health gauge
ups_battery_health{ups="nutdev1"} $(( 100 - CHARGE_DROP ))
# HELP ups_battery_charge_drop Battery charge drop during test
# TYPE ups_battery_charge_drop gauge
ups_battery_charge_drop{ups="nutdev1"} $CHARGE_DROP
# HELP ups_battery_test_timestamp Last battery test timestamp
# TYPE ups_battery_test_timestamp gauge
ups_battery_test_timestamp{ups="nutdev1"} $(date +%s)
EOF
```
## Referințe
- **NUT Commands:** https://networkupstools.org/docs/user-manual.chunked/ar01s07.html
- **Battery Testing Best Practices:** https://www.apc.com/us/en/faqs/FAQ000267818/
- **Proxmox Notifications:** https://pve.proxmox.com/wiki/Notifications
## Istoric Versiuni
- **v1.0** (2025-10-06)
- Release inițial
- Test automat baterie cu `test.battery.start.quick`
- Rapoarte HTML și text
- Email notifications
- Cron lunar (1 ale lunii)
- Evaluare sănătate baterie (4 nivele)
- Monitorizare recuperare 5 minute
---
**Autor:** Claude Code
**Ultima actualizare:** 2025-10-06