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
15 KiB
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, iarSmsInfo.mobileNumse gol. Nimeni nu ar fi aflat de o pană nici dacă softul mergea. - Oprire curată a Oracle: niciuna.
Shutdownconfigure.excutePrograme 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
- email (pleacă primul — în pană de curent poate cădea și switch-ul în orice moment)
Stop-Service OracleOraDB19Home1TNSListener— nu mai intră conexiuni noisqlplus / as sysdba→shutdown immediate, cu timeout 180 sStop-Service OracleServiceROA— plasă de siguranță; serviciul e el însuși configuratORA_ROA_SHUTDOWNTYPE=immediate,ORA_ROA_SHUTDOWN_TIMEOUT=90, deci și oprirea lui e curată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:
expirae 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șiupsTomcat— 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:\ViewPowera 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
-
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ă cutest-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.
- cât durează oprirea curată (
-
Vârsta acumulatorilor. Necunoscută. Pe cluster există deja criteriul de vârstă în testul lunar (
proxmox/cluster/ups/); aici nu există nimic echivalent. -
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.
-
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.