feat(ups): varsta acumulatorilor devine criteriu in testul lunar
Utilizatorul a confirmat ca acumulatorii au fost schimbati pe 2024-01-09 (data aproximativa). Asta scoate la iveala o limita a evaluarii pe tendinta: NUT a fost instalat pe 2025-10-06, cand acumulatorii aveau deja ~21 luni, deci linia de baza NU e o baterie noua. Raportul de 1.16x masoara degradarea peste o baterie care isi pierduse deja o parte din capacitate. Verdictul EXCELLENT e corect ca tendinta, dar nu inseamna "ca noua". Varsta devine criteriu separat, citit din /etc/nut/battery-install-date: sub 3 ani niciun efect, 3-4 ani nota vizibila in raport, peste 4 ani forteaza cel putin FAIR indiferent de tendinta. Fara fisier, scriptul merge normal si cere completarea lui. Verificat pe pvemini cu testul de baterie anulat, pe trei date: 32 luni (reala) -> EXCELLENT, 39 luni -> EXCELLENT cu nota, 56 luni -> FAIR fortat. Fallback-ul fara fisier intoarce varsta goala, nu eroare. Un bug prins la verificare: extragerea datei lua prima potrivire din fisier, care era un an dintr-un comentariu, si dadea varsta 0. Ambele extrageri sar acum peste liniile care incep cu #. Prag de 3 ani: 2027-01-09. Prag de 4 ani, cand testul incepe sa avertizeze singur: 2028-01-09. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RRyaDj39hPQ89SZS6URRpS
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
|
||||
LOGFILE="/var/log/ups-monthly-test.log"
|
||||
TRENDFILE="/var/log/ups-battery-trend.csv"
|
||||
BATTERY_DATE_FILE="/etc/nut/battery-install-date"
|
||||
UPS_NAME="nutdev1"
|
||||
UPS_USER="admin"
|
||||
UPS_PASS="parola99"
|
||||
@@ -33,6 +34,21 @@ log() {
|
||||
BASELINE_RUNS=6
|
||||
TREND_WINDOW=3
|
||||
|
||||
# Vârsta acumulatorilor, în luni, din $BATTERY_DATE_FILE (o singură linie,
|
||||
# format YYYY-MM-DD). Contează separat de tendință: linia de bază se poate să fi
|
||||
# fost măsurată pe o baterie deja îmbătrânită, caz în care raportul arată bine
|
||||
# fără ca bateria să fie bună. Vârsta e singurul reper absolut pe care îl avem.
|
||||
battery_age_months() {
|
||||
[ -r "$BATTERY_DATE_FILE" ] || return 0
|
||||
local d
|
||||
d=$(grep -v '^[[:space:]]*#' "$BATTERY_DATE_FILE" | grep -oE '[0-9]{4}-[0-9]{2}-[0-9]{2}' | head -1)
|
||||
[ -n "$d" ] || return 0
|
||||
local t0 t1
|
||||
t0=$(date -d "$d" +%s 2>/dev/null) || return 0
|
||||
t1=$(date +%s)
|
||||
awk -v a="$t0" -v b="$t1" 'BEGIN { printf "%.0f", (b - a) / 2629746 }'
|
||||
}
|
||||
|
||||
# Adaugă rularea curentă în fișierul de tendință
|
||||
append_trend() {
|
||||
if [ ! -f "$TRENDFILE" ]; then
|
||||
@@ -90,6 +106,7 @@ Battery Voltage Drop: {{ voltage_drop }}V
|
||||
Baseline Voltage Drop: {{ baseline_drop }}V ({{ baseline_runs }} rulari de referinta)
|
||||
Recent Median (3 run): {{ recent_drop }}V
|
||||
Trend vs Baseline: {{ trend_ratio }}x
|
||||
Battery Age: {{ battery_age }} luni (instalati {{ battery_install }})
|
||||
Minimum Charge Reached: {{ min_charge }}%
|
||||
Minimum Voltage: {{ min_voltage }}V
|
||||
Recovery Time: {{ recovery_time }}s
|
||||
@@ -183,6 +200,10 @@ EOFTEMPLATE
|
||||
<div class="metric-label">Baseline Drop</div>
|
||||
<div class="metric-value">{{ baseline_drop }}V</div>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<div class="metric-label">Battery Age</div>
|
||||
<div class="metric-value">{{ battery_age }} luni</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
@@ -233,7 +254,7 @@ EOFTEMPLATE
|
||||
# Template-urile se rescriu și dacă sunt dintr-o versiune veche, fără câmpurile
|
||||
# de tendință — altfel raportul ar ieși cu metrici lipsă.
|
||||
if [ ! -f "$TEMPLATE_DIR/ups-battery-test-subject.txt.hbs" ] || \
|
||||
! grep -q 'trend_ratio' "$TEMPLATE_DIR/ups-battery-test-body.txt.hbs" 2>/dev/null; then
|
||||
! grep -q 'battery_age' "$TEMPLATE_DIR/ups-battery-test-body.txt.hbs" 2>/dev/null; then
|
||||
log "Creating/updating notification templates..."
|
||||
create_templates
|
||||
fi
|
||||
@@ -366,6 +387,21 @@ log " Scădere tensiune: $VOLTAGE_DROP V (de la $BEFORE_VOLTAGE V la $MIN_VOLTA
|
||||
|
||||
append_trend "$VOLTAGE_DROP" "$MIN_VOLTAGE" "$CHARGE_DROP" "$BEFORE_LOAD" "$AFTER_LOAD" "$TEST_DURATION"
|
||||
|
||||
BATTERY_AGE=$(battery_age_months)
|
||||
BATTERY_INSTALL=$(grep -v '^[[:space:]]*#' "$BATTERY_DATE_FILE" 2>/dev/null | grep -oE '[0-9]{4}-[0-9]{2}-[0-9]{2}' | head -1)
|
||||
|
||||
# 0 = sub 3 ani, 1 = 3-4 ani (doar notă), 2 = peste 4 ani (forțează FAIR).
|
||||
# VRLA de 7Ah coboară sub 50% capacitate tipic la 3-4 ani, iar tendința nu prinde
|
||||
# asta dacă linia de bază a fost măsurată pe o baterie deja uzată.
|
||||
AGE_CLASS=0
|
||||
if [ -n "$BATTERY_AGE" ]; then
|
||||
if [ "$BATTERY_AGE" -ge 48 ]; then
|
||||
AGE_CLASS=2
|
||||
elif [ "$BATTERY_AGE" -ge 36 ]; then
|
||||
AGE_CLASS=1
|
||||
fi
|
||||
fi
|
||||
|
||||
TREND_ROWS=$(trend_rows)
|
||||
BASELINE_DROP=$(trend_median head $BASELINE_RUNS)
|
||||
RECENT_DROP=$(trend_median tail $TREND_WINDOW)
|
||||
@@ -386,6 +422,11 @@ log " Rulări înregistrate: $TREND_ROWS (fișier: $TRENDFILE)"
|
||||
log " Linie de bază (mediana primelor $BASELINE_RUNS_USED): ${BASELINE_DROP:-n/a} V"
|
||||
log " Recent (mediana ultimelor $TREND_WINDOW): ${RECENT_DROP:-n/a} V"
|
||||
log " Raport: ${TREND_RATIO}x"
|
||||
if [ -n "$BATTERY_AGE" ]; then
|
||||
log " Vârstă acumulatori: $BATTERY_AGE luni (instalați $BATTERY_INSTALL)"
|
||||
else
|
||||
log " Vârstă acumulatori: necunoscută ($BATTERY_DATE_FILE lipsește)"
|
||||
fi
|
||||
|
||||
BATTERY_HEALTH="UNKNOWN"
|
||||
HEALTH_CLASS="fair"
|
||||
@@ -393,6 +434,15 @@ HEALTH_EMOJI="[INFO]"
|
||||
HEALTH_DESCRIPTION=""
|
||||
RECOMMENDATIONS=""
|
||||
|
||||
AGE_NOTE=""
|
||||
case "$AGE_CLASS" in
|
||||
1) AGE_NOTE="<li>📅 Acumulatorii au $BATTERY_AGE luni (instalați $BATTERY_INSTALL). VRLA de 7Ah intră în zona de uzură la 3-4 ani — bugetează înlocuirea.</li>" ;;
|
||||
2) AGE_NOTE="<li>⚠️ Acumulatorii au $BATTERY_AGE luni (instalați $BATTERY_INSTALL), <strong>peste 4 ani</strong>. Verdictul e coborât la FAIR pe criteriu de vârstă, indiferent de tendință.</li>" ;;
|
||||
esac
|
||||
if [ -z "$BATTERY_AGE" ]; then
|
||||
AGE_NOTE="<li>Vârsta acumulatorilor e necunoscută — scrie data instalării în $BATTERY_DATE_FILE (YYYY-MM-DD).</li>"
|
||||
fi
|
||||
|
||||
# Praguri de tensiune absolută, ca plasă de siguranță. Nu înlocuiesc tendința —
|
||||
# prind cazul în care bateria cedează brusc, înainte să apuce media să urce.
|
||||
FLOOR=$(awk -v v="$MIN_VOLTAGE" 'BEGIN {
|
||||
@@ -402,7 +452,7 @@ FLOOR=$(awk -v v="$MIN_VOLTAGE" 'BEGIN {
|
||||
else { print "none" }
|
||||
}')
|
||||
|
||||
if [ "$TREND_ROWS" -lt $((BASELINE_RUNS + TREND_WINDOW)) ] && [ "$FLOOR" = "none" ]; then
|
||||
if [ "$TREND_ROWS" -lt $((BASELINE_RUNS + TREND_WINDOW)) ] && [ "$FLOOR" = "none" ] && [ "$AGE_CLASS" -lt 2 ]; then
|
||||
BATTERY_HEALTH="BASELINE"
|
||||
HEALTH_CLASS="good"
|
||||
HEALTH_EMOJI="[INFO]"
|
||||
@@ -424,9 +474,10 @@ elif [ "$TREND_RATIO" = "n/a" ]; then
|
||||
RECOMMENDATIONS="<ul><li>Verifică $TRENDFILE</li><li>Verifică dacă upsc întoarce battery.voltage</li></ul>"
|
||||
log " Sănătate baterie: NECUNOSCUTĂ (tendință incalculabilă)"
|
||||
else
|
||||
RATIO_CLASS=$(awk -v r="$TREND_RATIO" -v f="$FLOOR" 'BEGIN {
|
||||
RATIO_CLASS=$(awk -v r="$TREND_RATIO" -v f="$FLOOR" -v a="$AGE_CLASS" 'BEGIN {
|
||||
c = (r < 1.25) ? 1 : (r < 1.50) ? 2 : (r < 2.00) ? 3 : 4
|
||||
if (f == "warn" && c < 3) c = 3
|
||||
if (a == 2 && c < 3) c = 3
|
||||
print c
|
||||
}')
|
||||
case "$RATIO_CLASS" in
|
||||
@@ -465,6 +516,12 @@ else
|
||||
esac
|
||||
fi
|
||||
|
||||
# Nota de vârstă se lipește la finalul listei de recomandări, oricare ar fi
|
||||
# verdictul — inclusiv pe EXCELLENT, unde altfel s-ar pierde.
|
||||
if [ -n "$AGE_NOTE" ]; then
|
||||
RECOMMENDATIONS=$(echo "$RECOMMENDATIONS" | sed "s#</ul>\$#${AGE_NOTE}</ul>#")
|
||||
fi
|
||||
|
||||
# 7. Monitorizare recuperare (30 secunde)
|
||||
log ""
|
||||
log "Step 6: Monitorizare recuperare baterie..."
|
||||
@@ -515,6 +572,8 @@ my \$template_data = {
|
||||
'recent_drop' => '${RECENT_DROP:-n/a}',
|
||||
'trend_ratio' => '$TREND_RATIO',
|
||||
'baseline_runs' => '$BASELINE_RUNS_USED',
|
||||
'battery_age' => '${BATTERY_AGE:-necunoscuta}',
|
||||
'battery_install' => '${BATTERY_INSTALL:-necunoscuta}',
|
||||
'min_charge' => '$MIN_CHARGE',
|
||||
'min_voltage' => '$MIN_VOLTAGE',
|
||||
'before_charge' => '$BEFORE_CHARGE',
|
||||
@@ -560,6 +619,7 @@ log "Sănătate baterie: $BATTERY_HEALTH"
|
||||
log "Scădere încărcare: $CHARGE_DROP%"
|
||||
log "Scădere tensiune: $VOLTAGE_DROP V"
|
||||
log "Linie de bază: ${BASELINE_DROP:-n/a} V | recent: ${RECENT_DROP:-n/a} V | raport: ${TREND_RATIO}x"
|
||||
log "Vârstă acumulatori: ${BATTERY_AGE:-necunoscută} luni"
|
||||
log "Timp total: $RUNTIME secunde"
|
||||
log "========================================"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user