Auto: abcip-4.4 — _RefreshTagDb writeable system tag

Closes #241
This commit is contained in:
Joseph Doherty
2026-04-26 03:16:28 -04:00
parent e46e4de31f
commit e0e5e04e48
8 changed files with 877 additions and 45 deletions

View File

@@ -46,6 +46,14 @@
runs the SystemTagBrowse assertion — reads the value through the OPC UA
server + asserts it surfaces one of the canonical HostState strings.
NodeId form: ns=<n>;s=AbCip/<gateway>/_System/_ConnectionStatus.
.PARAMETER RefreshTagDbNodeId
Optional NodeId for the writeable _System/_RefreshTagDb trigger added in
PR abcip-4.4. When supplied, the script runs the RefreshTagDbWrite
assertion — writes True through the OPC UA server + reads back, asserting
the trigger latches to False (Kepware-style "always idle" semantics) and
the write itself surfaces Good. NodeId form:
ns=<n>;s=AbCip/<gateway>/_System/_RefreshTagDb.
#>
param(
@@ -60,7 +68,12 @@ param(
# discovery emits under each device. Optional — when wired, runs the
# SystemTagBrowse assertion that browses + reads the system folder through the OPC UA
# server. NodeId form: ns=<n>;s=AbCip/<gateway>/_System/_ConnectionStatus.
[string]$SystemConnectionStatusNodeId
[string]$SystemConnectionStatusNodeId,
# PR abcip-4.4 — NodeId for the writeable _System/_RefreshTagDb refresh-trigger.
# Mirrors the SystemConnectionStatusNodeId knob: optional, only runs the
# RefreshTagDbWrite assertion when supplied. NodeId form:
# ns=<n>;s=AbCip/<gateway>/_System/_RefreshTagDb.
[string]$RefreshTagDbNodeId
)
$ErrorActionPreference = "Stop"
@@ -243,5 +256,42 @@ if ($SystemConnectionStatusNodeId) {
}
}
# PR abcip-4.4 — _RefreshTagDb write-then-verify assertion. Writes True through the
# OPC UA server (the live driver intercepts the write + dispatches to RebrowseAsync
# against the cached IAddressSpaceBuilder) + reads back, asserting Kepware-style
# latch semantics: the trigger always reads False the moment the dispatch returns.
# Pairs with the existing rebrowse step driven by the AbCip CLI (issue #233) — both
# surfaces hit the same RebrowseAsync entry point, just from different sides of the
# OPC UA wire.
if ($RefreshTagDbNodeId) {
Write-Header "RefreshTagDbWrite (_System/_RefreshTagDb from $RefreshTagDbNodeId)"
$writeArgs = @($opcUaCli.PrefixArgs) + @(
"write", "-u", $OpcUaUrl, "-n", $RefreshTagDbNodeId, "-v", "true", "--type", "Boolean")
$writeOut = & $opcUaCli.File @writeArgs 2>&1
$writeJoined = ($writeOut -join "`n")
# The OPC UA Client CLI surfaces "Good" on success; a non-Good result still
# round-trips the literal status code so we can match generously.
$writeOk = $writeJoined -match "Good"
$readArgs = @($opcUaCli.PrefixArgs) + @("read", "-u", $OpcUaUrl, "-n", $RefreshTagDbNodeId)
$readOut = & $opcUaCli.File @readArgs 2>&1
$readJoined = ($readOut -join "`n")
# Kepware-style trigger reads always return false — assert the trigger isn't
# latched to true after the write. Match case-insensitively because the OPC UA
# Client CLI may render the value as "False" or "false".
$readFalse = $readJoined -imatch "false"
$passed = $writeOk -and $readFalse
$results += [PSCustomObject]@{
Name = "RefreshTagDbWrite"
Passed = $passed
Detail = if ($passed) {
"_RefreshTagDb write returned Good and read-back surfaced false — Kepware-style latch held"
} else {
"RefreshTagDb write/verify failed — write='$writeJoined' read='$readJoined'"
}
}
}
Write-Summary -Title "AB CIP e2e" -Results $results
if ($results | Where-Object { -not $_.Passed }) { exit 1 }