enet-validator/scripts/session/analyze_branch2.ps1

75 lines
3.8 KiB
PowerShell

[Console]::OutputEncoding = [Text.Encoding]::UTF8
$ErrorActionPreference = "Stop"
function H2B($hex) {
if (-not $hex) { return $null }
$n = $hex.Length / 2
$b = New-Object byte[] $n
for ($i = 0; $i -lt $n; $i++) { $b[$i] = [Convert]::ToByte($hex.Substring(2*$i, 2), 16) }
return $b
}
function UidNumArr($arr) { $v = [double]0; foreach ($x in $arr) { $v = $v * 256 + [int]$x }; return $v }
$lines = [IO.File]::ReadAllLines("$env:TEMP\opencode\ss123.tsv")
$queries = New-Object System.Collections.ArrayList
$pulses = New-Object System.Collections.ArrayList
foreach ($l in $lines) {
$p = $l -split "`t"; if ($p.Count -lt 5 -or -not $p[4]) { continue }
$b = H2B $p[4]; if ($b.Length -lt 0x30) { continue }
$t = [double]$p[0]
if ($p[1] -eq "192.168.123.113" -and $p[2] -eq "192.168.123.1" -and [int]$b[4] -eq 4 -and $b.Length -gt 0x5E -and $b.Length -lt 2000 -and $b[0x20] -eq 2 -and $b[0x21] -eq 0 -and $b[0x30] -eq 0 -and $b[0x3C] -eq 1 -and $b[0x3D] -eq 0x24) {
[void]$queries.Add(@{ t=$t; lo=(UidNumArr $b[0x53..0x58]); hi=(UidNumArr $b[0x59..0x5E]); loS=(($b[0x53..0x58] | ForEach-Object { $_.ToString("x2") }) -join ""); hiS=(($b[0x59..0x5E] | ForEach-Object { $_.ToString("x2") }) -join "") })
}
if ($p[1] -eq "192.168.123.1" -and $p[2] -eq "192.168.123.113" -and $b.Length -lt 200 -and $b[0x2A] -eq 0xAA) {
$uidBytes = @()
for ($i = 0; $i -lt 6; $i++) {
$b1 = $b[0x2B + 2*$i]; $b2 = $b[0x2C + 2*$i]
$uidBytes += ([int]$b1 -band 0x55) -bor ([int]$b2 -band 0xAA)
}
[void]$pulses.Add(@{ t=$t; uid=(UidNumArr $uidBytes); uidS=(($uidBytes | ForEach-Object { $_.ToString("x2") }) -join "") })
}
}
Write-Host ("cmd=24 查询={0} 脉冲={1}" -f $queries.Count, $pulses.Count)
# 分支范围分布
Write-Host "`n--- 分支范围 lo-hi 分布 (Top 15) ---"
$ranges = @{}
foreach ($q in $queries) { $k = "$($q.loS)-$($q.hiS)"; if (-not $ranges.ContainsKey($k)) { $ranges[$k] = 0 }; $ranges[$k]++ }
$ranges.GetEnumerator() | Sort-Object { [int]$_.Value } -Descending | Select-Object -First 15 | ForEach-Object { Write-Host (" {0} : {1}" -f $_.Key, $_.Value) }
# 核心验证: 范围内含灯具的查询 → 应答率; 范围外 → 应答率
$fx = @{}
foreach ($f in @("010734670125", "010734880900", "0899500026c9")) {
$n = [double]0; for ($i = 0; $i -lt 6; $i++) { $n = $n * 256 + [Convert]::ToInt32($f.Substring(2*$i, 2), 16) }
$fx[$f] = $n
}
$inN = 0; $inAns = 0; $outN = 0; $outAns = 0; $mismatches = 0
foreach ($q in $queries) {
$ans = @($pulses | Where-Object { $_.t -ge $q.t -and $_.t -lt $q.t + 0.1 })
$hasFx = $false; foreach ($f in $fx.Values) { if ($f -ge $q.lo -and $f -le $q.hi) { $hasFx = $true; break } }
if ($hasFx) {
$inN++
if ($ans.Count -gt 0) {
$inAns++
# 应答的 UID 是否都在范围内?
foreach ($a in $ans) { if ($a.uid -lt $q.lo -or $a.uid -gt $q.hi) { $mismatches++ } }
}
} else {
$outN++
if ($ans.Count -gt 0) { $outAns++ }
}
}
Write-Host "`n--- 分支语义验证 ---"
Write-Host (" 范围内有灯具的查询: {0}, 有应答: {1} ({2:F0}%)" -f $inN, $inAns, $(if ($inN) {100.0*$inAns/$inN} else {0}))
Write-Host (" 范围内无灯具的查询: {0}, 有应答: {1} ({2:F0}%)" -f $outN, $outAns, $(if ($outN) {100.0*$outAns/$outN} else {0}))
Write-Host (" 应答 UID 超出查询范围的次数: {0}" -f $mismatches)
# 有应答查询的时间序列样本
Write-Host "`n--- 样本: 分支范围 vs 应答 UID (前 15 条有应答) ---"
$shown = 0
foreach ($q in $queries) {
$ans = @($pulses | Where-Object { $_.t -ge $q.t -and $_.t -lt $q.t + 0.1 })
if ($ans.Count -eq 0) { continue }
Write-Host (" t={0,7:F2} [{1}..{2}] → {3}" -f $q.t, $q.loS, $q.hiS, (($ans | ForEach-Object { $_.uidS }) -join ","))
$shown++; if ($shown -ge 15) { break }
}