Files
ROMFASTSQL/docs/ups-server36-monitorizare.md
Marius 4b618dcb85 feat(ups): ramura "pe baterie" se poate testa fara scoaterea din priza
Lantul de protectie are doua jumatati. Prima - "UPS-ul chiar raporteaza trecerea
pe baterie?" - e deja dovedita de perechile de evenimente Kernel-Power 105 de la
panele reale din 2026. A doua - decizie, alerta, oprirea curata a Oracle - nu
avea cum sa fie exercitata decat asteptand o pana.

Acum monitorul accepta un SIMULARE.json care suprascrie citirea de alimentare.
Doua garzi, ca un fisier uitat sa nu opreasca serverul pe date inventate:
"expira" e obligatoriu si e sters automat la depasire, iar oprirea e in gol daca
nu se cere explicit "dryRun": false. Cat e activa, fiecare ciclu scrie WARN in
log si -Mode Status o afiseaza.

test-battery.ps1 conduce simularea si urmareste logul; sterge fisierul si daca e
intrerupt. Cu -ConfirmReal 'DA-OPRESTE-SERVERUL' devine repetitie reala pentru o
fereastra de mentenanta - singurul mod de a masura cat dureaza shutdown immediate
pe baza de productie, informatie de care depinde alegerea pragurilor.

Validat in gol pe 27.08.2026: detectie la 15:36:09 + email de pana, apoi exact
trei cicluri de confirmare, declansare pe pragul de 35% la 15:36:40 si secventa
parcursa integral. Oracle a ramas Running.

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

15 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/config.example.json șablon; fișierul real nu se comite (conține parola SMTP)

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

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ă (secțiunea 6, punctul 1).

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ă, cu monitorul dezarmat (DEZACTIVAT) și cu cineva care urmărește -Mode Status.

    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.

  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.