Bundles several feature streams that have been iterating on the working tree: - Developer Tools page (Debug-only via DEVELOPER_TOOLS symbol): hosts the identification card, manual KWP write + transaction log, ROM/EEPROM dump card with progress banner and completion message, persisted custom-commands library, persisted EEPROM passwords library. New service primitives: IKwpService.SendRawCustomAsync / ReadEepromAsync / ReadRomEepromAsync. Persistence mirrors the Clients XML pattern in two new files (custom_commands.xml, eeprom_passwords.xml). - Auto-test orchestrator (IAutoTestOrchestrator + AutoTestState): linear K-Line read -> unlock -> bench-on -> test sequence with snackbar UI and progress dialog VM, gated on dashboard alarms. - BIP-STATUS display: BipDisplayViewModel + BipDisplayView, RAM read at 0x0106 via IKwpService.ReadBipStatusAsync; status definitions in BipStatusDefinition. - Tests page redesign: TestSectionCard + PhaseTileView replacing the old TestPlanView/TestRunningView/TestDoneView/TestPreconditionsView/ TestSectionView controls and their VMs. - Pump command sliders: Fluent thick-track style with overhang thumb, click-anywhere-and-drag, mouse-wheel adjustment. - Window startup: app.manifest declares PerMonitorV2 DPI awareness, MainWindow installs a WM_GETMINMAXINFO hook in OnSourceInitialized and maximizes there (after the hook is in place) so the app fits the work area exactly on any display configuration. - Misc: PercentToPixelsConverter, seed_aliases.py one-shot pump-alias importer, tools/Import-BipStatus.ps1, kline_eeprom_spec.md and dump-functions reference docs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
231 lines
8.1 KiB
PowerShell
231 lines
8.1 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
Parses BIP-STATUS sections from PSG5-PI CFG files and injects
|
|
<BipStatus> blocks into every preinjection="true" pump in pumps.xml.
|
|
|
|
.DESCRIPTION
|
|
Applies the 7-def Config B (T15014 family) to every preinjection=true pump.
|
|
Reactions are forced to 0 (display-only pass per implementation plan).
|
|
A timestamped backup of pumps.xml is created before modification.
|
|
|
|
.PARAMETER CfgDir
|
|
Directory containing the CFG files.
|
|
|
|
.PARAMETER PumpsXml
|
|
Path to pumps.xml. Defaults to %USERPROFILE%\.HC_APTBS\config\pumps.xml.
|
|
|
|
.PARAMETER DryRun
|
|
Print the generated XML only; do NOT modify pumps.xml.
|
|
|
|
.EXAMPLE
|
|
powershell -ExecutionPolicy Bypass -File Import-BipStatus.ps1
|
|
powershell -ExecutionPolicy Bypass -File Import-BipStatus.ps1 -DryRun
|
|
#>
|
|
param(
|
|
[string]$CfgDir = (Join-Path $PSScriptRoot '..\old_source\HerlicScripts\CFGs'),
|
|
[string]$PumpsXml = (Join-Path $env:USERPROFILE '.HC_APTBS\config\pumps.xml'),
|
|
[switch]$DryRun
|
|
)
|
|
|
|
Set-StrictMode -Version Latest
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
$BipCfgFiles = @(
|
|
'T15009.CFG','T15014.CFG','T15017.CFG','T15018.CFG','T15019.CFG',
|
|
'T15021.CFG','T18309.CFG','T18603.CFG','T18607.CFG','T31804.CFG'
|
|
)
|
|
|
|
# ---- Parse one CFG file -------------------------------------------------------
|
|
function Parse-BipConfig {
|
|
param([string]$cfgPath)
|
|
|
|
$defMap = @{}
|
|
$vector = $null
|
|
|
|
$lines = [System.IO.File]::ReadAllLines($cfgPath, [System.Text.Encoding]::GetEncoding('ISO-8859-1'))
|
|
|
|
foreach ($line in $lines) {
|
|
$raw = ($line -split '\\')[0].Trim()
|
|
if (-not $raw) { continue }
|
|
|
|
$cols = $raw -split '\|' | ForEach-Object { $_.Trim() }
|
|
$key = $cols[0]
|
|
|
|
if ($key -eq 'BIP-STATUS') {
|
|
if ($cols.Count -ge 5) { $vector = $cols[4].Trim() }
|
|
}
|
|
elseif ($key -match '^BIP-STATUS(\d+)-DEF$') {
|
|
$idx = [int]$Matches[1]
|
|
$hexStr = if ($cols.Count -ge 5) { $cols[4].Trim() } else { '0000' }
|
|
$spfnRaw = if ($cols.Count -ge 7) { $cols[6].Trim() } else { '9' }
|
|
$spfn = if ($spfnRaw -eq 'B') { 11 } else {
|
|
$n = 9; [int]::TryParse($spfnRaw, [ref]$n) | Out-Null; $n
|
|
}
|
|
$defMap[$idx] = [ordered]@{
|
|
Index = $idx
|
|
Enabled = $true
|
|
HexPattern = [Convert]::ToUInt16($hexStr, 16)
|
|
Reaction = 0
|
|
SpecialFunction= $spfn
|
|
Description = ''
|
|
}
|
|
}
|
|
elseif ($key -match '^BIP-STATUS(\d+)$') {
|
|
$idx = [int]$Matches[1]
|
|
$desc = if ($cols.Count -ge 5) { $cols[4].Trim() } else { '' }
|
|
if ($defMap.ContainsKey($idx)) { $defMap[$idx].Description = $desc }
|
|
}
|
|
}
|
|
|
|
# Apply enable vector: char at position i = '1' means bit i enabled
|
|
if ($vector) {
|
|
$vArr = $vector.ToCharArray()
|
|
foreach ($idx in @($defMap.Keys)) {
|
|
if ($idx -lt $vArr.Count) {
|
|
$defMap[$idx].Enabled = ($vArr[$idx] -eq '1')
|
|
}
|
|
}
|
|
}
|
|
|
|
return @($defMap.GetEnumerator() | Sort-Object { $_.Key } | ForEach-Object { $_.Value })
|
|
}
|
|
|
|
# ---- Parse all CFG files ------------------------------------------------------
|
|
Write-Host ""
|
|
Write-Host "=== Parsing CFG files from: $CfgDir ===" -ForegroundColor Cyan
|
|
Write-Host ""
|
|
|
|
$configs = @{}
|
|
foreach ($cfgName in $BipCfgFiles) {
|
|
$cfgPath = Join-Path $CfgDir $cfgName
|
|
if (-not (Test-Path $cfgPath)) {
|
|
Write-Warning "CFG not found, skipping: $cfgPath"
|
|
continue
|
|
}
|
|
$parsed = Parse-BipConfig -cfgPath $cfgPath
|
|
$cnt = $parsed.Count
|
|
Write-Host " $cfgName -- $cnt BIP definitions"
|
|
$configs[$cfgName] = $parsed
|
|
}
|
|
|
|
# T15014 = 7-def Config B (most complete; safe to apply to all preinjection pumps)
|
|
$configB = $null
|
|
if ($configs.ContainsKey('T15014.CFG')) { $configB = $configs['T15014.CFG'] }
|
|
if ($null -eq $configB) {
|
|
# Fallback: any 7-def config
|
|
foreach ($k in $configs.Keys) {
|
|
if ($configs[$k].Count -eq 7) { $configB = $configs[$k]; break }
|
|
}
|
|
}
|
|
if ($null -eq $configB -and $configs.ContainsKey('T15009.CFG')) {
|
|
$configB = $configs['T15009.CFG']
|
|
}
|
|
if ($null -eq $configB) {
|
|
Write-Error "No BIP config could be parsed. Aborting."
|
|
exit 1
|
|
}
|
|
|
|
$defCount = $configB.Count
|
|
Write-Host ""
|
|
Write-Host "Using $defCount-def Config B (T15014 family) for all preinjection pumps." -ForegroundColor Green
|
|
|
|
# ---- Generate preview XML -----------------------------------------------------
|
|
if ($DryRun) {
|
|
Write-Host ""
|
|
Write-Host "=== Generated BipStatus XML (DryRun -- pumps.xml NOT modified) ===" -ForegroundColor Yellow
|
|
Write-Host " <BipStatus>"
|
|
foreach ($d in $configB) {
|
|
$en = if ($d.Enabled) { 'true' } else { 'false' }
|
|
$hex = '0x{0:X4}' -f [int]$d.HexPattern
|
|
$desc= $d.Description
|
|
Write-Host (" <Bit index=""{0}"" enabled=""{1}"" hex=""{2}"" reaction=""{3}"" specialFunction=""{4}"">{5}</Bit>" -f $d.Index, $en, $hex, $d.Reaction, $d.SpecialFunction, $desc)
|
|
}
|
|
Write-Host " </BipStatus>"
|
|
Write-Host ""
|
|
exit 0
|
|
}
|
|
|
|
# ---- Load pumps.xml -----------------------------------------------------------
|
|
if (-not (Test-Path $PumpsXml)) {
|
|
Write-Error "pumps.xml not found: $PumpsXml"
|
|
exit 1
|
|
}
|
|
|
|
$backup = $PumpsXml -replace '\.xml$', ('_bip_backup_{0}.xml' -f (Get-Date -Format 'yyyyMMdd_HHmmss'))
|
|
Copy-Item $PumpsXml $backup -Force
|
|
Write-Host "Backed up pumps.xml -> $backup" -ForegroundColor DarkGray
|
|
|
|
[System.Reflection.Assembly]::LoadWithPartialName('System.Xml.Linq') | Out-Null
|
|
$xdoc = [System.Xml.Linq.XDocument]::Load($PumpsXml)
|
|
|
|
$pumps = @($xdoc.Descendants([System.Xml.Linq.XName]'Pump') | Where-Object {
|
|
$attr = $_.Attribute('preinjection')
|
|
($null -ne $attr) -and ($attr.Value -eq 'true')
|
|
})
|
|
|
|
Write-Host ""
|
|
Write-Host "Found $($pumps.Count) preinjection=true pump(s) in pumps.xml." -ForegroundColor Cyan
|
|
|
|
$updated = 0
|
|
foreach ($pump in $pumps) {
|
|
$idAttr = $pump.Attribute('id')
|
|
$pumpId = if ($null -ne $idAttr) { $idAttr.Value } else { '(unknown)' }
|
|
|
|
# Remove any existing BipStatus
|
|
$existing = $pump.Element([System.Xml.Linq.XName]'BipStatus')
|
|
if ($null -ne $existing) {
|
|
$existing.Remove()
|
|
Write-Host " Replaced BipStatus on pump $pumpId"
|
|
} else {
|
|
Write-Host " Added BipStatus on pump $pumpId"
|
|
}
|
|
|
|
# Build new BipStatus element
|
|
$bipElem = [System.Xml.Linq.XElement]::new([System.Xml.Linq.XName]'BipStatus')
|
|
foreach ($d in $configB) {
|
|
$en = if ($d.Enabled) { 'true' } else { 'false' }
|
|
$hex = '0x{0:X4}' -f [int]$d.HexPattern
|
|
$bit = [System.Xml.Linq.XElement]::new([System.Xml.Linq.XName]'Bit',
|
|
[System.Xml.Linq.XAttribute]::new('index', [string]$d.Index),
|
|
[System.Xml.Linq.XAttribute]::new('enabled', $en),
|
|
[System.Xml.Linq.XAttribute]::new('hex', $hex),
|
|
[System.Xml.Linq.XAttribute]::new('reaction', [string]$d.Reaction),
|
|
[System.Xml.Linq.XAttribute]::new('specialFunction', [string]$d.SpecialFunction),
|
|
[System.Xml.Linq.XText]::new($d.Description)
|
|
)
|
|
$bipElem.Add($bit)
|
|
}
|
|
|
|
# Insert after <Params>, or append if absent
|
|
$paramsElem = $pump.Element([System.Xml.Linq.XName]'Params')
|
|
if ($null -ne $paramsElem) {
|
|
$paramsElem.AddAfterSelf($bipElem)
|
|
} else {
|
|
$pump.Add($bipElem)
|
|
}
|
|
$updated++
|
|
}
|
|
|
|
if ($updated -eq 0) {
|
|
Write-Warning "No pumps updated. Restoring backup."
|
|
Copy-Item $backup $PumpsXml -Force
|
|
exit 0
|
|
}
|
|
|
|
# Save UTF-8 without BOM
|
|
$settings = [System.Xml.XmlWriterSettings]::new()
|
|
$settings.Encoding = [System.Text.UTF8Encoding]::new($false)
|
|
$settings.Indent = $true
|
|
$settings.IndentChars = ' '
|
|
$settings.OmitXmlDeclaration = $false
|
|
|
|
$writer = [System.Xml.XmlWriter]::Create($PumpsXml, $settings)
|
|
try { $xdoc.Save($writer) } finally { $writer.Close() }
|
|
|
|
Write-Host ""
|
|
Write-Host "Done. Updated $updated pump(s) in pumps.xml." -ForegroundColor Green
|
|
Write-Host "Backup: $backup" -ForegroundColor DarkGray
|
|
Write-Host ""
|
|
Write-Host "Next: run the app, select a preinjection pump, and verify BipDisplayView shows $defCount BIP rows." -ForegroundColor Cyan
|
|
Write-Host ""
|