Files
ROMFASTSQL/docs/ups-server36-monitorizare.md
Marius b874cfac37 docs(ups): uneltele testului de autonomie si ce s-a aflat despre gauge
Cele trei unelte adaugate la ultimul commit (set-praguri, trace-baterie,
start-trace) nu aparaeu in documentatie. Adaugate in tabelul de fisiere si
descrise ca procedura in sectiunea de operare, in ordinea reala de folosire:
largeste praguri -> porneste trace -> scoate din priza -> opreste trace ->
restaureaza praguri.

Sectiunea 6 punctul 1 primeste rezultatul scoaterii din priza de pe 27.08:
autonomia tot nu e masurata (trei minute sunt prea putine), dar s-a vazut ca
gauge-ul de procent al acestui UPS nu e de incredere - 96% -> 65% -> 90% in
100 de secunde la revenirea curentului. Pragul de 35% se sprijina exact pe
cifra asta, iar confirmPolls=3 (45 s) e mai scurt decat fereastra de zgomot.
ACLineStatus, in schimb, a fost impecabil - de aici directia pentru pragurile
definitive: timpul pe baterie devine criteriul principal.

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

19 KiB
Raw Blame History

Monitorizare UPS pe serverul Oracle de producție (10.0.20.36)

Server: ROA-CARAPETRU2 / 10.0.20.36 — Windows 11 Pro, Oracle 19c SE2, instanța ROA. Acces: ssh -p 22122 Administrator@10.0.20.36.

Pe scurt: ViewPower nu a putut niciodată dialoga cu acest UPS și a fost dezactivat pe 10 august 2026, lăsând serverul fără nicio alertare timp de 17 zile. UPS-ul, în schimb, comunică perfect cu Windows pe canalul HID nativ. Monitorizarea nouă folosește exact acel canal. ViewPower e închis și nu mai pornește.

Se citește împreună cu incident-2026-08-10-server36-standby.md — cele două se leagă în seara de 10 august.


1. Diagnosticul: ce era stricat, de fapt

UPS-ul comunică — și a comunicat tot timpul

Verificare Rezultat (27.08.2026)
USB\VID_0665&PID_5161\HID_UPS Status OK, enumerat corect
HID\...&MI_01, driver HidBatt „HID UPS Battery", Status OK
Win32_Battery HID UPS, Status OK, BatteryStatus 2 (pe rețea), încărcare 100%
Kernel-Power ID 105 (schimbare sursă) perechi AC↔baterie reale: 10 iun, 13 mai, 5 mai, 25 feb 2026

Perechile de evenimente 105 sunt dovada care închide discuția: la fiecare pană reală Windows a văzut trecerea pe baterie și revenirea. Ultima pană: 10 iunie 2026. Din 10 august (dezactivarea ViewPower) până azi nu a mai fost niciuna, deci nu s-a pierdut niciun eveniment — noroc, nu proiectare.

ViewPower nu vorbește limba acestui UPS

C:\ViewPower\log\log4j.log acoperă 6 aug 15:40:37 → 10 aug 22:34:11 (patru treceri peste miezul nopții, numărate în fișier). Din 5787 de linii, 5777 sunt QPI return(NAK. Zero citiri reușite: nicio tensiune, nicio stare de baterie, niciun eveniment electric.

QPI este comanda de identificare a protocolului Voltronic. UPS-ul răspunde (NAK — „comandă nesuportată" — deci ViewPower rămâne blocat în bucla de identificare și nu ajunge niciodată să interogheze starea.

Nu e o problemă de port: GlobalConfig.portName=USB1F0775B7 din config\ups.properties corespunde exact interfeței HID\VID_0665&PID_5161&MI_00\8&1F0775B7&0&0000. ViewPower e legat de dispozitivul corect; setul de comenzi e greșit. UPS-ul vorbește HID Power Device standard — de aceea îl citește Windows fără niciun driver suplimentar — nu dialectul text pe care îl trimite ViewPower. Nu există setare care să repare asta.

Cronologia serii de 10 august

22:24:12  upsTomcat pornit          (o ultimă încercare de repornire)
22:24:31  ups.properties rescris
22:34:11  ultimul QPI return(NAK
22:34:44  System 7040: upsMonitor  auto start → disabled
22:34:46  System 7040: upsTomcat   demand start → disabled

Cineva a încercat să repare, nu a reușit și a dezactivat serviciile. Din acel moment: zero monitorizare. Tray-ul care se deschidea și dădea start ups monitor service error! încerca, de fapt, să pornească un serviciu pus pe Disabled (registry Start=4).

Ce nu exista oricum, chiar și cu ViewPower funcțional

  • Alertare: niciuna. Logul arată ---------emailReceivers.length()-----0, iar SmsInfo.mobileNums e gol. Nimeni nu ar fi aflat de o pană nici dacă softul mergea.
  • Oprire curată a Oracle: niciuna. Shutdownconfigure.excuteProgram e gol — nu rula niciun script înainte de shutdown.
  • Regula proprie „30 min pe baterie → oprire" (batModeShutdown=true, batModeShutdownTime=30) era inactivă odată cu serviciile.
  • Vârsta acumulatorilor neurmărită (GlobalConfig.batteryLifetime=0).

Plasa care exista, totuși

Planul de alimentare Windows, pe canalul HID care funcționează:

Setare Valoare
Critical battery level 20 %
Critical battery action Shut down (și pe AC, și pe DC)
Low battery level / action 40 % / Do nothing
Reserve battery level 25 %

Deci serverul s-ar fi oprit singur la 20 %, dar brutal: fără avertisment, fără shutdown immediate pe Oracle, fără ca cineva să afle.


2. Ce s-a pus în loc

Un singur script PowerShell care citește GetSystemPowerStatus — exact API-ul pe care îl folosește Windows pentru propria acțiune de „critical battery". Consecința practică: dacă oprirea automată a Windows-ului ar funcționa, funcționează și scriptul; nu există un al doilea canal care să se strice separat.

Fișier în repo Rol
scripts/ups-monitor/ups-monitor.ps1 monitorul propriu-zis (buclă + moduri de test)
scripts/ups-monitor/install-ups-monitor.ps1 instalare: copiere, config.json, ACL, task programat
scripts/ups-monitor/test-battery.ps1 test: simulează „pe baterie" fără scoaterea din priză
scripts/ups-monitor/test-comms-loss.ps1 test: dezactivează temporar bateria HID și verifică alerta de comunicație
scripts/ups-monitor/set-praguri.ps1 schimbă pragurile din config.json fără a atinge parola SMTP, și repornește taskul
scripts/ups-monitor/trace-baterie.ps1 înregistrează curba de descărcare într-un CSV (rulează ca task, sub SYSTEM)
scripts/ups-monitor/start-trace.ps1 pornește / oprește (-Stop) taskul de înregistrare
scripts/ups-monitor/config.example.json șablon; fișierul real nu se comite (conține parola SMTP)

Ultimele trei sunt uneltele testului de autonomie — se folosesc împreună, vezi secțiunea 3.

Pe server:

C:\ROMFAST\ups-monitor\ups-monitor.ps1
C:\ROMFAST\ups-monitor\config.json      <- parola SMTP; ACL: doar SYSTEM + Administratori
C:\ROMFAST\ups-monitor\state.json       <- starea între cicluri
C:\ROMFAST\ups-monitor\log\ups-monitor-YYYY-MM.log
C:\ROMFAST\_deploy\                     <- punctul de livrare (de aici rulează instalarea)

Task programat ROMFAST UPS Monitor, rulează ca NT AUTHORITY\SYSTEM (cont deja membru ORA_DBA pe acest server, deci sqlplus / as sysdba merge fără parolă).

Ce face

Eveniment Acțiune
Trecere pe baterie email imediat: „PANĂ DE CURENT"
Revenirea curentului email cu durata cât s-a stat pe baterie
UPS-ul nu mai e văzut de Windows email de alertă, repetat la 24 h cât ține defectul
Comunicația revine email de confirmare
Prag de oprire atins email, apoi oprire curată

Pragurile de oprire

10 minute pe baterie   SAU   încărcare ≤ 35 %
                              (Windows rămâne plasa de siguranță, la 20 %)

Se declanșează doar după 3 citiri consecutive care confirmă starea pe baterie — o citire aberantă nu poate opri serverul. Iar dacă UPS-ul nu comunică, scriptul nu ia nicio decizie de oprire; alertează și atât.

Secvența de oprire

  1. email (pleacă primul — în pană de curent poate cădea și switch-ul în orice moment)
  2. Stop-Service OracleOraDB19Home1TNSListener — nu mai intră conexiuni noi
  3. sqlplus / as sysdba → shutdown immediate, cu timeout 180 s
  4. Stop-Service OracleServiceROA — plasă de siguranță; serviciul e el însuși configurat ORA_ROA_SHUTDOWNTYPE=immediate, ORA_ROA_SHUTDOWN_TIMEOUT=90, deci și oprirea lui e curată
  5. shutdown /s /f /t 30

La revenirea curentului serverul nu pornește singur decât dacă e activat Restore on AC power loss în BIOS. De verificat separat, la prima intervenție fizică.


3. Operare

# starea curentă: UPS, Oracle, task, ultimele linii de log
powershell -ExecutionPolicy Bypass -File C:\ROMFAST\ups-monitor\ups-monitor.ps1 -Mode Status

# verifică alertarea pe email
powershell -ExecutionPolicy Bypass -File C:\ROMFAST\ups-monitor\ups-monitor.ps1 -Mode TestMail

# parcurge secvența de oprire în gol — nu oprește nimic
powershell -ExecutionPolicy Bypass -File C:\ROMFAST\ups-monitor\ups-monitor.ps1 -Mode TestShutdown

Ce s-a validat la punerea în funcțiune (27.08.2026)

Test Rezultat
Citirea stării pe rețea, 100 %, Win32_Battery: HID UPS, Status=OK
-Mode TestMail email primit — mail.romfast.ro:587, STARTTLS, ups@romfast.ro
-Mode TestShutdown (dry-run) secvența parcursă integral; Oracle a rămas Running
Pierderea comunicației (test-comms-loss.ps1) dispozitiv oprit 15:24:44 → alertă 15:26:44 (exact 8 cicluri × 15 s) + email; reactivare → „comunicația a revenit" + email; Win32_Battery înapoi la 1 instanță
Taskul rulează ca SYSTEM proces ups-monitor.ps1 -Mode Run, state.json actualizat la fiecare ciclu
Trecerea reală pe baterie (scos din priză, 15:47:45 → 15:50:46) tranziția s-a văzut instantaneu în ambele sensuri; email de pană la 15:47:55, email de revenire la 15:50:56

Toate cele patru ramuri de alertare au emis email. Testul cu scoaterea din priză a durat doar trei minute — prea puțin pentru autonomie, dar suficient cât să valideze semnalul de sursă și să descopere problema gauge-ului (secțiunea 6, punctul 1).

Testul „pe baterie", fără scoaterea din priză

Lanțul de protecție are două jumătăți, și se testează separat:

Jumătatea Cum se validează
UPS → Windows (chiar raportează trecerea pe baterie?) deja dovedită de istoric: perechile de evenimente Kernel-Power 105 la panele reale din 10 iun, 13 mai, 5 mai, 25 feb 2026
Windows → script → alertă → oprirea Oracle test-battery.ps1, oricând, fără hardware
# repetiție în gol - sigură oricând, în producție
powershell -ExecutionPolicy Bypass -File C:\ROMFAST\_deploy\test-battery.ps1 -Percent 30 -Minute 3

# doar trecerea pe baterie, fără atingerea pragului de oprire
powershell -ExecutionPolicy Bypass -File C:\ROMFAST\_deploy\test-battery.ps1 -Percent 80 -Minute 3

Scriptul scrie SIMULARE.json lângă config.json; cât există, monitorul folosește valorile din el în locul citirii reale. Două gărzi, ca un fișier uitat să nu oprească serverul pe date inventate:

  • expira e obligatoriu. Fără el fișierul e ignorat; la depășire, monitorul îl șterge singur.
  • Oprirea e în gol, dacă nu se cere explicit "dryRun": false.

Cât e activă simularea, fiecare ciclu scrie în log o linie WARN SIMULARE ACTIVA, iar -Mode Status o afișează. test-battery.ps1 șterge fișierul și dacă e întrerupt.

Repetiție reală, într-o fereastră de mentenanță — Oracle chiar se oprește și serverul chiar se închide, dar UPS-ul rămâne în priză:

powershell -ExecutionPolicy Bypass -File C:\ROMFAST\_deploy\test-battery.ps1 -ConfirmReal 'DA-OPRESTE-SERVERUL'

Asta e singurul mod de a verifica de-adevăratelea cât durează shutdown immediate pe baza de producție — informația de care depinde alegerea pragurilor.

Rămâne netestabilă prin simulare doar autonomia reală a UPS-ului: câte minute ține sub sarcina actuală. Aceea cere scoaterea din priză — procedura e mai jos.

Testul de autonomie, cu scoaterea din priză

Trei unelte, în ordinea asta. Toate rulează pe server, prin ssh -p 22122.

# 1. lărgește pragurile, ca monitorul să nu oprească serverul în timpul testului
#    (scriptul repornește singur taskul - configurația se citește doar la pornirea buclei)
powershell -ExecutionPolicy Bypass -File C:\ROMFAST\ups-monitor\set-praguri.ps1 -Minute 60 -Procent 15

# 2. pornește înregistrarea curbei de descărcare
powershell -ExecutionPolicy Bypass -File C:\ROMFAST\ups-monitor\start-trace.ps1 -IntervalSecunde 15

#    --- abia acum se scoate din priză; minimum 15-20 de minute, ca să se vadă panta ---

# 3. după ce s-a băgat înapoi: oprește înregistrarea și restaurează pragurile de producție
powershell -ExecutionPolicy Bypass -File C:\ROMFAST\ups-monitor\start-trace.ps1 -Stop
powershell -ExecutionPolicy Bypass -File C:\ROMFAST\ups-monitor\set-praguri.ps1 -Minute 10 -Procent 35

Înregistrarea rulează ca task programat sub SYSTEM, nu în sesiunea SSH — dacă în pană cade switch-ul și conexiunea moare, măsurătoarea continuă. Datele rămân în C:\ROMFAST\ups-monitor\log\trace-baterie.csv; scriptul adaugă la fișierul existent, deci CSV-ul unui test anterior se arhivează întâi sub alt nume, altfel se amestecă rulările.

Două lucruri de verificat înainte de a scoate ștecherul: pragul de procent lărgit sub 20 % înseamnă că plasa de siguranță rămâne Windows-ul, nu scriptul; și e util ca gauge-ul să fie la 100 %, nu abia revenit dintr-un test anterior.

Dezarmare de urgență (monitorul rămâne pornit, dar nu mai ia nicio decizie):

New-Item -ItemType File 'C:\ROMFAST\ups-monitor\DEZACTIVAT'

Ștergerea fișierului îl rearmează, fără repornire. Există și "enabled": false în config.json, dar acela cere repornirea taskului.

Reinstalare / schimbare praguri (de pe stația de administrare):

scp -P 22122 ups-monitor.ps1 install-ups-monitor.ps1 Administrator@10.0.20.36:'C:/ROMFAST/_deploy/'
ssh -p 22122 Administrator@10.0.20.36 "powershell -ExecutionPolicy Bypass -File C:\ROMFAST\_deploy\install-ups-monitor.ps1 -SmtpPassword ... -ShutdownAfterMinutesOnBattery 10 -ShutdownAtBatteryPercent 35"

Emailuri: de la ups@romfast.ro către marius.mutu@romfast.ro, prin mail.romfast.ro:587 (STARTTLS). Același cont SMTP pe care îl folosesc și cele trei noduri Proxmox — credențialele sunt în /etc/postfix/sasl_passwd pe noduri.


4. Ce s-a întâmplat cu ViewPower

  • procesele ViewPower.exe, upsTray.exe, javaw.exe — oprite;
  • serviciile upsMonitor și upsTomcat — rămân Disabled (erau deja, din 10 august);
  • nu există autostart — nici în Run (HKLM/HKCU), nici în folderele Startup; procesele văzute pe 27 august fuseseră pornite manual;
  • instalarea din C:\ViewPower a fost lăsată pe disc, ca referință pentru loguri și configurație.

Efect secundar util: nu mai ascultă nimic pe 15178 și 8005 — un Tomcat 8.5.51 cu OpenJDK 11.0.7 (2020–2021) nu mai stă pornit degeaba pe un server de producție.

Dezinstalarea completă (C:\ViewPower\Uninstaller.exe) e opțională. Înainte de ea merită salvat C:\ViewPower\datas — baza Derby de ~71 MB cu istoricul softului.


5. Capcane plătite (ca să nu se redescopere)

Task-urile programate sunt oprite de Windows exact când serverul trece pe baterie. E comportamentul implicit. Fără -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries la New-ScheduledTaskSettingsSet, monitorul ar fi fost ucis fix în secunda în care avea treabă. Asta e greșeala care ar fi trecut neobservată până la prima pană reală.

$PSScriptRoot este gol în valoarea implicită a unui parametru. La legarea parametrilor încă nu e populat, deci [string]$ConfigPath = (Join-Path $PSScriptRoot 'config.json') crapă cu „Cannot bind argument to parameter 'Path' because it is an empty string". Se rezolvă în corpul scriptului.

[TimeSpan]::MaxValue pentru -RepetitionDuration e respins, deși e documentat ca „la nesfârșit": „The task XML contains a value which is incorrectly formatted or out of range. Duration: P99999999DT23H59M59S". Se omite parametrul — asta chiar înseamnă la nesfârșit.

PowerShell 5.1 nu acceptă if/try ca expresie într-un literal de hashtable (@{ x = if (...) {...} }) sau la atribuire din try. Scriptul e scris în consecință; se verifică înainte de livrare cu:

$e=$null; [System.Management.Automation.PSParser]::Tokenize((Get-Content x.ps1 -Raw), [ref]$e); $e

Ghilimelele simple supraviețuiesc prin ssh → powershell -File. -SmtpPassword '#Ups2020#' a ajuns în config.json ca '#Ups2020#', cu tot cu apostrofuri, iar serverul de mail a răspuns „SMTP AUTH is required for message submission on port 587" — adică nu s-a autentificat deloc. Pentru orice valoare cu caractere speciale: se trimite un .ps1 cu scp și se rulează acolo, nu se construiește comanda din ghilimele.

Fișierul .ps1 e intenționat fără diacritice. PowerShell 5.1 citește un .ps1 fără BOM ca ANSI; diacriticele din literalii de șir ar ajunge corupte în emailuri. Documentația (.md) nu are constrângerea asta.


6. Rămâne de făcut

  1. Testul de autonomie reală. Pragurile de 10 min / 35 % sunt alese conservator, nu măsurate. Sunt două necunoscute distincte, iar doar una cere scoaterea din priză:

    • cât durează oprirea curată (shutdown immediate + închiderea Windows-ului) — se află dintr-o repetiție reală cu test-battery.ps1 -ConfirmReal ..., într-o fereastră de mentenanță, cu UPS-ul în priză;
    • cât ține UPS-ul sub sarcina actuală — asta chiar cere scoaterea din priză, după procedura din secțiunea 3.

    Pragul corect e „autonomia măsurată minus durata opririi, cu marjă". Până când ambele sunt măsurate, pragurile rămân o presupunere rezonabilă, nu o garanție.

    Ce s-a aflat pe 27.08.2026, dintr-o scoatere din priză de trei minute: autonomia n-a fost măsurată — trei minute sunt prea puține, iar singura cifră existentă rămâne estimarea proprie a UPS-ului, ~70 de minute, nevalidată. S-a aflat însă altceva, mai important.

    Gauge-ul de procent al acestui UPS nu e de încredere. Pe baterie a scăzut lent și monoton (100 % → 96 % în trei minute), dar la revenirea curentului a sărit haotic:

    15:50:26  baterie 96%
    15:50:46  rețea   65%     <- revine curentul
    15:51:06  rețea   75%
    15:51:46  rețea   90%
    

    96 → 65 → 90 în 100 de secunde. Nicio baterie nu se încarcă 25 de puncte în 80 de secunde, deci nu e încărcare — e recalibrare, sau zgomot în jurul tranziției. (La 12 minute după test gauge-ul era tot la 90 %.)

    Consecința pentru configurația actuală: pragul de 35 % se sprijină exact pe numărul ăsta nesigur, iar garda de confirmare (confirmPolls = 3, adică 45 s) e mai scurtă decât fereastra de zgomot observată (~80–100 s). Riscul e în ambele sensuri: o citire aberantă sub 35 % ar putea opri inutil baza de producție, iar una optimistă ar putea întârzia oprirea.

    Semnalul de sursă (ACLineStatus) a fost, în schimb, impecabil — tranzițiile s-au văzut instantaneu în ambele sensuri. De aici, direcția pentru pragurile definitive:

    • timpul pe baterie devine criteriul principal, fiindcă se sprijină pe ACLineStatus;
    • procentul rămâne doar plasă secundară, cu valoare mai mică și cu confirmPolls crescut peste fereastra de zgomot (≥ 8 cicluri = 2 min);
    • de evaluat BatteryLifeTime ca al treilea criteriu — în acest test a scăzut lin și monoton, spre deosebire de procent. Există deja shutdownAtRuntimeSeconds în config.json, momentan 0 = dezactivat.
  2. Vârsta acumulatorilor. Necunoscută. Pe cluster există deja criteriul de vârstă în testul lunar (proxmox/cluster/ups/); aici nu există nimic echivalent.

  3. BIOS: Restore on AC power loss. De verificat la prima intervenție fizică — altfel după o pană lungă serverul rămâne oprit până vine cineva să apese butonul.

  4. Legătura cu incidentul din 10 august: stările de somn (S3) sunt încă disponibile pe acest server. O oprire declanșată de UPS ajunge la shutdown /s, nu la sleep, deci nu e afectată — dar problema de fond rămâne deschisă în documentul incidentului.