# 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`](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-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 ```powershell # 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 | **Netestat, pentru că cere pană reală:** trecerea pe baterie, pragurile de oprire și oprirea efectivă a Oracle. Ramura de decizie e comună cu cea testată în dry-run, dar declanșatorul nu a fost exercitat pe hardware. Vezi punctul 1 din secțiunea 6. **Dezarmare de urgență** (monitorul rămâne pornit, dar nu mai ia nicio decizie): ```powershell 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): ```powershell 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: ```powershell $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. Nu se știe cât ține UPS-ul sub sarcina actuală, deci nu se știe dacă cele 10 minute lasă destul timp pentru `shutdown immediate` + oprirea Windows-ului. Se măsoară scoțând UPS-ul din priză, cu monitorul **dezarmat** (`DEZACTIVAT`) și cu cineva care urmărește `-Mode Status`. Până atunci, pragurile sunt 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.