Add CYD host PC info panel with serial SI protocol and LVGL bars.
ESP32 shows CPU/GPU/RAM/disk from host/send_sysinfo.ps1 over USB; firmware packages for 2.8 and 3.5 included. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
162
host/send_sysinfo.ps1
Normal file
162
host/send_sysinfo.ps1
Normal file
@@ -0,0 +1,162 @@
|
||||
# Push this PC's CPU / GPU / RAM / disk stats to CYD over USB serial.
|
||||
# Usage:
|
||||
# .\send_sysinfo.ps1
|
||||
# .\send_sysinfo.ps1 -Port COM5
|
||||
# .\send_sysinfo.ps1 -Port COM5 -IntervalMs 1000
|
||||
|
||||
param(
|
||||
[string]$Port = "",
|
||||
[int]$IntervalMs = 1000,
|
||||
[int]$Baud = 460800
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
function Find-CydPort {
|
||||
$ports = @()
|
||||
try {
|
||||
Add-Type -AssemblyName System.IO.Ports -ErrorAction SilentlyContinue | Out-Null
|
||||
$ports = [System.IO.Ports.SerialPort]::GetPortNames() | Sort-Object
|
||||
} catch {}
|
||||
if (-not $ports -or $ports.Count -eq 0) {
|
||||
$ports = Get-CimInstance Win32_SerialPort -ErrorAction SilentlyContinue |
|
||||
Select-Object -ExpandProperty DeviceID | Sort-Object
|
||||
}
|
||||
if (-not $ports -or $ports.Count -eq 0) {
|
||||
throw "No serial ports found. Plug in the CYD USB cable."
|
||||
}
|
||||
if ($ports.Count -eq 1) { return $ports[0] }
|
||||
Write-Host "Available ports: $($ports -join ', ')"
|
||||
$pick = $ports[-1]
|
||||
Write-Host "Using last port: $pick (override with -Port)"
|
||||
return $pick
|
||||
}
|
||||
|
||||
function Sanitize([string]$s, [int]$max = 40) {
|
||||
if (-not $s) { return "" }
|
||||
$t = ($s -replace '[|=\r\n]', ' ').Trim()
|
||||
if ($t.Length -gt $max) { $t = $t.Substring(0, $max).Trim() }
|
||||
return $t
|
||||
}
|
||||
|
||||
function Get-CpuName {
|
||||
$p = Get-CimInstance Win32_Processor -ErrorAction SilentlyContinue | Select-Object -First 1
|
||||
if (-not $p) { return "CPU" }
|
||||
$n = [string]$p.Name
|
||||
# Shorten common Intel/AMD noise
|
||||
$n = $n -replace '\(R\)|\(TM\)|CPU @.*|with Radeon.*', ''
|
||||
$n = ($n -replace '\s+', ' ').Trim()
|
||||
return Sanitize $n 44
|
||||
}
|
||||
|
||||
function Get-CpuPct {
|
||||
try {
|
||||
$c = Get-CimInstance Win32_Processor -ErrorAction Stop
|
||||
$vals = @($c | ForEach-Object { [double]$_.LoadPercentage })
|
||||
if ($vals.Count -eq 0) { return 0.0 }
|
||||
return [math]::Round(($vals | Measure-Object -Average).Average, 1)
|
||||
} catch {
|
||||
return 0.0
|
||||
}
|
||||
}
|
||||
|
||||
function Get-GpuName {
|
||||
$gpus = Get-CimInstance Win32_VideoController -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.Name -and $_.Name -notmatch 'Microsoft Basic|Remote Desktop' }
|
||||
if (-not $gpus) { return "GPU" }
|
||||
# Prefer NVIDIA / AMD discrete if present
|
||||
$pick = $gpus | Where-Object { $_.Name -match 'NVIDIA|GeForce|RTX|GTX|Radeon|AMD' } |
|
||||
Select-Object -First 1
|
||||
if (-not $pick) { $pick = $gpus | Select-Object -First 1 }
|
||||
$n = [string]$pick.Name
|
||||
$n = $n -replace 'NVIDIA GeForce ', 'RTX/GTX '
|
||||
$n = $n -replace 'AMD ', ''
|
||||
return Sanitize $n 44
|
||||
}
|
||||
|
||||
function Get-GpuPct {
|
||||
# 1) nvidia-smi
|
||||
$smi = Get-Command nvidia-smi -ErrorAction SilentlyContinue
|
||||
if ($smi) {
|
||||
try {
|
||||
$out = & nvidia-smi --query-gpu=utilization.gpu --format=csv,noheader,nounits 2>$null
|
||||
if ($LASTEXITCODE -eq 0 -and $out) {
|
||||
$first = ([string]($out | Select-Object -First 1)).Trim()
|
||||
if ($first -match '^\d+') { return [double]$first }
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
# 2) Windows GPU Engine counter (may need a few samples)
|
||||
try {
|
||||
$counters = Get-Counter '\GPU Engine(*)\Utilization Percentage' -ErrorAction Stop
|
||||
$samples = $counters.CounterSamples |
|
||||
Where-Object { $_.CookedValue -ge 0 -and $_.InstanceName -match 'engtype_3D|engtype_Graphics' }
|
||||
if ($samples) {
|
||||
$sum = ($samples | Measure-Object -Property CookedValue -Sum).Sum
|
||||
if ($sum -gt 100) { $sum = 100 }
|
||||
return [math]::Round($sum, 1)
|
||||
}
|
||||
} catch {}
|
||||
return -1.0
|
||||
}
|
||||
|
||||
function Get-RamGb {
|
||||
$os = Get-CimInstance Win32_OperatingSystem -ErrorAction Stop
|
||||
$total = [math]::Round($os.TotalVisibleMemorySize / 1MB, 1)
|
||||
$free = [math]::Round($os.FreePhysicalMemory / 1MB, 1)
|
||||
$used = [math]::Round($total - $free, 1)
|
||||
return @{ Used = $used; Total = $total }
|
||||
}
|
||||
|
||||
function Get-DiskGb {
|
||||
$d = Get-CimInstance Win32_LogicalDisk -Filter "DeviceID='C:'" -ErrorAction SilentlyContinue
|
||||
if (-not $d) {
|
||||
$d = Get-CimInstance Win32_LogicalDisk -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.DriveType -eq 3 -and $_.Size -gt 0 } |
|
||||
Select-Object -First 1
|
||||
}
|
||||
if (-not $d -or -not $d.Size) {
|
||||
return @{ Used = 0.0; Total = 0.0 }
|
||||
}
|
||||
$total = [math]::Round($d.Size / 1GB, 1)
|
||||
$free = [math]::Round($d.FreeSpace / 1GB, 1)
|
||||
$used = [math]::Round($total - $free, 1)
|
||||
return @{ Used = $used; Total = $total }
|
||||
}
|
||||
|
||||
function Build-Line {
|
||||
$hostName = Sanitize $env:COMPUTERNAME 36
|
||||
$cpu = Get-CpuName
|
||||
$cpuPct = Get-CpuPct
|
||||
$gpu = Get-GpuName
|
||||
$gpuPct = Get-GpuPct
|
||||
$ram = Get-RamGb
|
||||
$disk = Get-DiskGb
|
||||
$gpuField = if ($gpuPct -lt 0) { "gpu%=-1" } else { "gpu%=$gpuPct" }
|
||||
return "SI|host=$hostName|cpu=$cpu|cpu%=$cpuPct|gpu=$gpu|$gpuField|ram=$($ram.Used)/$($ram.Total)|disk=$($disk.Used)/$($disk.Total)"
|
||||
}
|
||||
|
||||
if (-not $Port) { $Port = Find-CydPort }
|
||||
|
||||
Add-Type -AssemblyName System.IO.Ports
|
||||
$sp = [System.IO.Ports.SerialPort]::new($Port, $Baud)
|
||||
$sp.ReadTimeout = 200
|
||||
$sp.WriteTimeout = 2000
|
||||
$sp.NewLine = "`n"
|
||||
$sp.DtrEnable = $true
|
||||
$sp.RtsEnable = $true
|
||||
|
||||
try {
|
||||
$sp.Open()
|
||||
Write-Host "Sending host info -> $Port @ $Baud every ${IntervalMs}ms (Ctrl+C to stop)"
|
||||
Start-Sleep -Milliseconds 400
|
||||
while ($true) {
|
||||
$line = Build-Line
|
||||
$sp.WriteLine($line)
|
||||
Write-Host $line
|
||||
Start-Sleep -Milliseconds $IntervalMs
|
||||
}
|
||||
} finally {
|
||||
if ($sp.IsOpen) { $sp.Close() }
|
||||
$sp.Dispose()
|
||||
}
|
||||
Reference in New Issue
Block a user