rs485-lpc/Verify-Rs485.ps1

78 lines
3.7 KiB
PowerShell
Raw Permalink Normal View History

# Verify-Rs485.ps1 — 验证 rs485_verification_plan.md §2 离线项 S1~S4(-Hardware 时附 COM 口探测)
param(
[switch]$Hardware
)
$ErrorActionPreference = 'Stop'
$script:pass = 0; $script:fail = 0
function Check($name, $cond, $detail) {
if ($cond) { $script:pass++; Write-Host (" [PASS] {0} {1}" -f $name, $detail) }
else { $script:fail++; Write-Host (" [FAIL] {0} {1}" -f $name, $detail) }
}
$dir = Split-Path -Parent $MyInvocation.MyCommand.Path
Write-Host "== S1 帧编码 =="
$expected = [byte[]](0x42, 0x52, 0x54, 0x3D, 0x38, 0x30, 0x0A)
$payload = "BRT=80\n" -replace '\\n', "`n" -replace '\\r', "`r"
$bytes = [System.Text.Encoding]::ASCII.GetBytes($payload)
$same = ($bytes.Count -eq $expected.Count) -and (-not (Compare-Object $bytes $expected -SyncWindow 0))
Check "S1a BRT=80\n字节序列" $same ("| " + (($bytes | ForEach-Object { $_.ToString('X2') }) -join ' '))
$p1 = "A\r\nB" -replace '\\r', "`r" -replace '\\n', "`n"
$CR = $p1.Contains([char]0x0D); $LF = $p1.Contains([char]0x0A)
Check "S1b \r\n 转义还原" ($CR -and $LF) ("| CR={0} LF={1}" -f $CR, $LF)
Write-Host "== S2 行帧解析 =="
$buf = "BRT=0`nBRT=25`r`nBRT=50`nBRT="
$parts = $buf -split "`n"
$complete = $parts[0..($parts.Count - 2)]
$rest = $parts[-1]
$clean = @($complete | ForEach-Object { $_.TrimEnd("`r") })
Check "S2a 完整行数" ($clean.Count -eq 3) ("| " + ($clean -join ' / '))
Check "S2b 半包留缓冲" ($rest -eq 'BRT=') ("| tail='$rest'")
Check "S2c 行内容无损" (($clean -join ',') -eq 'BRT=0,BRT=25,BRT=50') "| 无CR残留且顺序正确"
Write-Host "== S3 Lua 脚本结构 =="
$luaPath = Join-Path $dir 'lpc_serial_brt.lua'
Check "S3a 脚本文件存在" (Test-Path $luaPath) "| $luaPath"
if (Test-Path $luaPath) {
$lua = Get-Content $luaPath -Raw
Check "S3b 读取通配符变量" ($lua -match 'get_trigger_variable\(1\)') "| get_trigger_variable(1).integer(Designer 2 语法)"
Check "S3c 边界钳位" ($lua -match 'if v < 0' -and $lua -match 'if v > 100') "| 0..100"
Check "S3d 强度换算" ($lua -match 'v / 100') "| 百分比→0..1"
Check "S3e 组主亮度调光" ($lua -match 'get_group' -and $lua -match 'set_master_intensity') "| get_group(n):set_master_intensity"
$balance = ([regex]::Matches($lua, '\(')).Count -eq ([regex]::Matches($lua, '\)')).Count
Check "S3f 括号配平" $balance "| 粗略语法完整性"
}
Write-Host "== S4 工具模式 =="
$tool = Join-Path $dir 'Test-Rs485.ps1'
$errs = $null
$null = [System.Management.Automation.Language.Parser]::ParseFile($tool, [ref]$null, [ref]$errs)
Check "S4a Test-Rs485.ps1 语法" ($errs.Count -eq 0) ("| 语法错误 {0} 个" -f $errs.Count)
$raw = Get-Content $tool -Raw
foreach ($mode in 'ListPorts', 'Send', 'Listen', 'Interactive') {
Check "S4b 模式 -$mode" ($raw -match "\`$$mode|\[$mode\]|-$mode") "| 参数存在"
}
if ($Hardware) {
Write-Host "== 硬件探测(只开/关端口,不写数据)=="
foreach ($p in ([System.IO.Ports.SerialPort]::GetPortNames() | Sort-Object)) {
$sp = $null
try {
$sp = New-Object System.IO.Ports.SerialPort($p, 9600, 'None', 8, 'One')
$sp.ReadTimeout = 200
$sp.Open(); $sp.Close()
Write-Host (" [OPEN] {0} 可用(候选 USB-485,拔插对比确认)" -f $p)
} catch {
Write-Host (" [BUSY] {0} 被占用或不可开:{1}" -f $p, $_.Exception.Message.Trim())
} finally {
if ($sp -and $sp.IsOpen) { $sp.Close() }
}
}
}
Write-Host ""
Write-Host "========================================"
Write-Host ("RS485 链路离线验证结果: PASS={0} FAIL={1}" -f $script:pass, $script:fail)
if ($script:fail -eq 0) { Write-Host ">>> 离线验证全部通过,可进入阶段1(H1 单机自发自收)<<<" }