diff --git a/scripts/ups-monitor/set-praguri.ps1 b/scripts/ups-monitor/set-praguri.ps1 new file mode 100644 index 0000000..352250d --- /dev/null +++ b/scripts/ups-monitor/set-praguri.ps1 @@ -0,0 +1,66 @@ +<# +.SYNOPSIS + Schimba pragurile de oprire din config.json fara sa atinga parola SMTP, + si reporneste monitorul ca sa le citeasca. + +.DESCRIPTION + Se ruleaza PE SERVER, ridicat (Administrator). + + Configuratia e citita o singura data, la pornirea buclei, deci orice modificare + cere repornirea taskului - de asta se ocupa scriptul. + + Fara parametri, doar afiseaza pragurile curente. + +.EXAMPLE + # praguri largite pentru un test de autonomie + powershell -ExecutionPolicy Bypass -File .\set-praguri.ps1 -Minute 60 -Procent 25 + +.EXAMPLE + # inapoi la valorile de productie + powershell -ExecutionPolicy Bypass -File .\set-praguri.ps1 -Minute 10 -Procent 35 +#> +[CmdletBinding()] +param( + [string]$InstallDir = 'C:\ROMFAST\ups-monitor', + [ValidateRange(1, 1440)][int]$Minute, + [ValidateRange(1, 99)][int]$Procent, + [switch]$FaraRepornire +) + +Set-StrictMode -Version 2.0 +$ErrorActionPreference = 'Stop' + +$path = Join-Path $InstallDir 'config.json' +$cfg = Get-Content -LiteralPath $path -Raw -Encoding UTF8 | ConvertFrom-Json + +Write-Host ("Praguri curente : {0} min pe baterie / {1}% incarcare" -f ` + $cfg.shutdownAfterMinutesOnBattery, $cfg.shutdownAtBatteryPercent) + +if (-not $Minute -and -not $Procent) { + Write-Host 'Nimic de schimbat (da -Minute si/sau -Procent).' + return +} + +if ($Minute) { $cfg.shutdownAfterMinutesOnBattery = $Minute } +if ($Procent) { $cfg.shutdownAtBatteryPercent = $Procent } + +$cfg | ConvertTo-Json -Depth 5 | Set-Content -LiteralPath $path -Encoding UTF8 +Write-Host ("Praguri noi : {0} min pe baterie / {1}% incarcare" -f ` + $cfg.shutdownAfterMinutesOnBattery, $cfg.shutdownAtBatteryPercent) + +if ($cfg.shutdownAtBatteryPercent -le 20) { + Write-Warning 'Pragul e sub cel al Windows-ului (20%): Windows va opri serverul primul, brutal, inaintea opririi curate.' +} + +if ($FaraRepornire) { + Write-Warning 'Monitorul NU a fost repornit - inca ruleaza cu pragurile vechi.' + return +} + +Stop-ScheduledTask -TaskName 'ROMFAST UPS Monitor' +Start-Sleep -Seconds 3 +Start-ScheduledTask -TaskName 'ROMFAST UPS Monitor' +Start-Sleep -Seconds 18 + +$log = Join-Path $InstallDir ('log\ups-monitor-{0}.log' -f (Get-Date -Format 'yyyy-MM')) +Get-Content -LiteralPath $log -Tail 2 | ForEach-Object { " $_" } diff --git a/scripts/ups-monitor/start-trace.ps1 b/scripts/ups-monitor/start-trace.ps1 new file mode 100644 index 0000000..16045a0 --- /dev/null +++ b/scripts/ups-monitor/start-trace.ps1 @@ -0,0 +1,69 @@ +<# +.SYNOPSIS + Porneste (sau opreste) inregistrarea curbei de descarcare, ca task programat + sub SYSTEM - ca sa nu moara odata cu sesiunea SSH. + +.EXAMPLE + powershell -ExecutionPolicy Bypass -File .\start-trace.ps1 + powershell -ExecutionPolicy Bypass -File .\start-trace.ps1 -Stop +#> +[CmdletBinding()] +param( + [string]$InstallDir = 'C:\ROMFAST\ups-monitor', + [ValidateRange(5, 300)][int]$IntervalSecunde = 20, + [switch]$Stop +) + +Set-StrictMode -Version 2.0 +$ErrorActionPreference = 'Stop' + +$TaskName = 'ROMFAST UPS Trace' +$csv = Join-Path $InstallDir 'log\trace-baterie.csv' +$stopFile = Join-Path $InstallDir 'log\STOP-TRACE' + +if ($Stop) { + New-Item -ItemType File -Path $stopFile -Force | Out-Null + Start-Sleep -Seconds ($IntervalSecunde + 5) + if (Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue) { + Stop-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue + Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false + } + Remove-Item -LiteralPath $stopFile -Force -ErrorAction SilentlyContinue + Write-Host "Inregistrare oprita. Datele raman in $csv" + if (Test-Path -LiteralPath $csv) { + Write-Host '' + Get-Content -LiteralPath $csv -Tail 10 | ForEach-Object { " $_" } + } + return +} + +$script = Join-Path $InstallDir 'trace-baterie.ps1' +if (-not (Test-Path -LiteralPath $script)) { + throw "Lipseste $script - copiaza-l intai in $InstallDir" +} + +$action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument ( + '-NoProfile -NonInteractive -ExecutionPolicy Bypass -File "{0}" -IntervalSecunde {1}' -f $script, $IntervalSecunde) + +# Aceleasi doua setari ca la monitor: fara ele, Windows opreste taskul exact cand +# serverul trece pe baterie - adica exact cand incepe ce vrem sa masuram. +$settings = New-ScheduledTaskSettingsSet ` + -AllowStartIfOnBatteries ` + -DontStopIfGoingOnBatteries ` + -MultipleInstances IgnoreNew ` + -ExecutionTimeLimit ([TimeSpan]::Zero) + +$principal = New-ScheduledTaskPrincipal -UserId 'NT AUTHORITY\SYSTEM' -LogonType ServiceAccount -RunLevel Highest + +if (Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue) { + Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false +} +Register-ScheduledTask -TaskName $TaskName -Description 'Inregistreaza curba de descarcare a UPS-ului in timpul unui test de autonomie.' ` + -Action $action -Settings $settings -Principal $principal | Out-Null + +Start-ScheduledTask -TaskName $TaskName +Start-Sleep -Seconds ($IntervalSecunde + 8) + +Get-ScheduledTask -TaskName $TaskName | Format-Table -AutoSize TaskName, State +Write-Host "CSV: $csv" +if (Test-Path -LiteralPath $csv) { Get-Content -LiteralPath $csv -Tail 5 | ForEach-Object { " $_" } } diff --git a/scripts/ups-monitor/trace-baterie.ps1 b/scripts/ups-monitor/trace-baterie.ps1 new file mode 100644 index 0000000..0e796be --- /dev/null +++ b/scripts/ups-monitor/trace-baterie.ps1 @@ -0,0 +1,93 @@ +<# +.SYNOPSIS + Inregistreaza local, in CSV, curba de descarcare a UPS-ului in timpul unui test + de autonomie cu scoaterea din priza. + +.DESCRIPTION + Se ruleaza ca task programat, sub SYSTEM, ca sa supravietuiasca inchiderii + sesiunii SSH - exact scenariul unui test de pana, unde reteaua poate cadea odata + cu curentul daca switch-ul nu e pe UPS. + + Scrie o linie la fiecare interval, indiferent de starea alimentarii, si se + opreste singur dupa MaxOre sau cand apare fisierul STOP-TRACE langa CSV. + Fisierul CSV e singura sursa sigura de date daca reteaua pica: monitorul + propriu-zis noteaza doar evenimentele, nu fiecare citire. + + Se porneste cu start-trace.ps1, care inregistreaza si taskul. + +.EXAMPLE + powershell -ExecutionPolicy Bypass -File .\trace-baterie.ps1 -IntervalSecunde 20 +#> +[CmdletBinding()] +param( + [string]$OutFile = 'C:\ROMFAST\ups-monitor\log\trace-baterie.csv', + [ValidateRange(5, 300)][int]$IntervalSecunde = 20, + [ValidateRange(1, 24)][int]$MaxOre = 8 +) + +Set-StrictMode -Version 2.0 +$ErrorActionPreference = 'Stop' + +if (-not ('TracePowerStatus' -as [type])) { + Add-Type -TypeDefinition @' +using System; +using System.Runtime.InteropServices; + +[StructLayout(LayoutKind.Sequential)] +public struct TRACE_POWER_STATUS { + public byte ACLineStatus; + public byte BatteryFlag; + public byte BatteryLifePercent; + public byte SystemStatusFlag; + public int BatteryLifeTime; + public int BatteryFullLifeTime; +} + +public static class TracePowerStatus { + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool GetSystemPowerStatus(out TRACE_POWER_STATUS status); +} +'@ +} + +$dir = Split-Path -Parent $OutFile +if (-not (Test-Path -LiteralPath $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null } + +$stopFile = Join-Path $dir 'STOP-TRACE' +Remove-Item -LiteralPath $stopFile -Force -ErrorAction SilentlyContinue + +if (-not (Test-Path -LiteralPath $OutFile)) { + Set-Content -LiteralPath $OutFile -Encoding UTF8 ` + -Value 'ora;sursa;procent;autonomie_sec;acLineStatus;batteryFlag' +} +Add-Content -LiteralPath $OutFile -Encoding UTF8 ` + -Value ('# start {0}' -f (Get-Date -Format 'yyyy-MM-dd HH:mm:ss')) + +$pana = (Get-Date).AddHours($MaxOre) + +while ((Get-Date) -lt $pana -and -not (Test-Path -LiteralPath $stopFile)) { + try { + $st = New-Object TRACE_POWER_STATUS + [void][TracePowerStatus]::GetSystemPowerStatus([ref]$st) + + $sursa = switch ($st.ACLineStatus) { + 0 { 'baterie' } + 1 { 'retea' } + default { 'necunoscut' } + } + $procent = if ($st.BatteryLifePercent -le 100) { [int]$st.BatteryLifePercent } else { '' } + $autonomie = if ($st.BatteryLifeTime -ge 0) { [int]$st.BatteryLifeTime } else { '' } + + Add-Content -LiteralPath $OutFile -Encoding UTF8 -Value ( + '{0};{1};{2};{3};{4};{5}' -f (Get-Date -Format 'HH:mm:ss'), $sursa, $procent, + $autonomie, [int]$st.ACLineStatus, [int]$st.BatteryFlag) + } catch { + Add-Content -LiteralPath $OutFile -Encoding UTF8 -Value ( + '{0};EROARE;;;;{1}' -f (Get-Date -Format 'HH:mm:ss'), $_.Exception.Message) + } + Start-Sleep -Seconds $IntervalSecunde +} + +Add-Content -LiteralPath $OutFile -Encoding UTF8 ` + -Value ('# stop {0}' -f (Get-Date -Format 'yyyy-MM-dd HH:mm:ss'))