@@ -306,17 +306,19 @@ wire up?" to "what's our scan rate / tag count?" without leaving the OPC UA
|
||||
address space. The values come straight from the live
|
||||
`IHostConnectivityProbe` + `DriverHealth` surfaces — reads bypass libplctag
|
||||
and are served from the in-memory snapshot the probe loop / read loop
|
||||
updates.
|
||||
updates. PR abcip-4.4 added `_RefreshTagDb` as a sixth, writeable entry —
|
||||
the Kepware-style refresh trigger.
|
||||
|
||||
### What it ships
|
||||
|
||||
| Variable | Type | Source | Notes |
|
||||
|---|---|---|---|
|
||||
| `_ConnectionStatus` | String | `HostState` | `Running` / `Stopped` / `Unknown` / `Faulted`. Mirrors what the connectivity probe sees. |
|
||||
| `_ScanRate` | Float64 | `AbCipProbeOptions.Interval` | Configured probe interval in milliseconds — compare against `_LastScanTimeMs` to spot wire stretch. |
|
||||
| `_TagCount` | Int32 | `_tagsByName` | Discovered tag count for this device, excluding `_System/*`. |
|
||||
| `_DeviceError` | String | `DriverHealth.LastError` | Most recent error message; empty when the device is healthy. |
|
||||
| `_LastScanTimeMs` | Float64 | `ReadAsync` wall-clock | Duration of the most-recent `ReadAsync` iteration on this device. |
|
||||
| Variable | Type | Access | Source | Notes |
|
||||
|---|---|---|---|---|
|
||||
| `_ConnectionStatus` | String | ViewOnly | `HostState` | `Running` / `Stopped` / `Unknown` / `Faulted`. Mirrors what the connectivity probe sees. |
|
||||
| `_ScanRate` | Float64 | ViewOnly | `AbCipProbeOptions.Interval` | Configured probe interval in milliseconds — compare against `_LastScanTimeMs` to spot wire stretch. |
|
||||
| `_TagCount` | Int32 | ViewOnly | `_tagsByName` | Discovered tag count for this device, excluding `_System/*`. |
|
||||
| `_DeviceError` | String | ViewOnly | `DriverHealth.LastError` | Most recent error message; empty when the device is healthy. |
|
||||
| `_LastScanTimeMs` | Float64 | ViewOnly | `ReadAsync` wall-clock | Duration of the most-recent `ReadAsync` iteration on this device. |
|
||||
| `_RefreshTagDb` | Boolean | **Operate** | n/a (write-only trigger) | PR abcip-4.4 — Kepware-style refresh trigger. Reads always return `false`. Writing any truthy value (`true`, non-zero number, `"true"` / `"1"` strings, case-insensitive) dispatches to `RebrowseAsync` against the device's cached `IAddressSpaceBuilder`. Falsy / unparseable writes are no-ops that report `Good` so a UI that resets the trigger flag doesn't see a phantom error. The `AbCip.RefreshTriggers` diagnostic counter increments per truthy write. |
|
||||
|
||||
### When the snapshot updates
|
||||
|
||||
@@ -346,19 +348,59 @@ otopcua-client-cli read -u opc.tcp://localhost:4840 \
|
||||
|
||||
The driver-side reference embeds the device host address (the
|
||||
`_System/<device>/<name>` form) so the dispatcher can route by device
|
||||
without an additional registry. PR abcip-4.4 will turn `_RefreshTagDb` into
|
||||
a writeable refresh trigger; everything 4.3 ships is `ViewOnly`.
|
||||
without an additional registry. PR abcip-4.4 turned `_RefreshTagDb` into
|
||||
a writeable refresh trigger; the rest of the surface remains `ViewOnly`.
|
||||
|
||||
### Refreshing the tag DB via OPC UA write
|
||||
|
||||
PR abcip-4.4 wires `_RefreshTagDb` to the same `RebrowseAsync` entry point
|
||||
the CLI's `rebrowse` command exercises (issue #233). Operators have two
|
||||
roughly-equivalent ways to force a controller-side `@tags` re-walk after a
|
||||
program download:
|
||||
|
||||
```powershell
|
||||
# Path A — OPC UA write to the system tag (production / Admin UI path)
|
||||
otopcua-client-cli write -u opc.tcp://localhost:4840 \
|
||||
-n "ns=2;s=AbCip/ab://10.0.0.5/1,0/_System/_RefreshTagDb" \
|
||||
-v true --type Boolean
|
||||
|
||||
# Path B — direct CLI rebrowse against a transient driver (admin / debug path)
|
||||
otopcua-abcip-cli rebrowse -g ab://10.0.0.5/1,0
|
||||
```
|
||||
|
||||
Both paths drop the UDT template cache + re-run the enumerator walk. Path A
|
||||
is the operator-facing surface (the same `IDriverControl.RebrowseAsync`
|
||||
contract, just dispatched from the OPC UA write surface instead of an
|
||||
in-process call). Path B spins up its own driver instance so it doesn't
|
||||
share the live server's cache, which makes it useful for one-off
|
||||
controller-side validation.
|
||||
|
||||
The `AbCip.RefreshTriggers` driver-diagnostics counter increments per
|
||||
successful truthy write, so the Admin UI / driver-diagnostics RPC can show
|
||||
a "Refreshes since boot" tile that pairs naturally with the existing
|
||||
`WritesSuppressed` / `WritesPassedThrough` write-coalescer counters.
|
||||
|
||||
### Verification
|
||||
|
||||
- **Unit**: `AbCipSystemTagSourceTests`
|
||||
(`tests/.../AbCip.Tests`) — covers snapshot round-trip, two-device
|
||||
isolation, recognised-name lookup, default-shape on unseeded devices,
|
||||
discovery emits the five canonical nodes, and `ReadAsync` dispatches
|
||||
discovery emits the six canonical nodes, and `ReadAsync` dispatches
|
||||
through the source instead of libplctag.
|
||||
- **Unit**: `AbCipRefreshTagDbTests`
|
||||
(`tests/.../AbCip.Tests`) — PR abcip-4.4 — covers discovery emits the
|
||||
trigger as Operate, reads always return `false`, truthy/falsy/null write
|
||||
semantics, the `AbCip.RefreshTriggers` counter, two-device counter
|
||||
independence, defends-in-depth `BadNotWritable` for read-only system
|
||||
variables, no-op-Good when no builder is cached yet, and mixed-batch
|
||||
routing alongside ordinary tag writes.
|
||||
- **Integration**: `AbCipSystemTagDiscoveryTests`
|
||||
(`tests/.../AbCip.IntegrationTests`) — `[AbServerFact]` connects to a
|
||||
real `ab_server`, browses `_System/`, reads each variable, asserts
|
||||
every one returns Good with a non-null value.
|
||||
- **E2E**: `scripts/e2e/test-abcip.ps1` — see the *SystemTagBrowse*
|
||||
assertion.
|
||||
- **Integration**: `AbCipRefreshTagDbTests`
|
||||
(`tests/.../AbCip.IntegrationTests`) — PR abcip-4.4 — `[AbServerFact]`
|
||||
drives a `_RefreshTagDb` write, asserts the template cache drops + the
|
||||
per-device counter advances against a live `ab_server`.
|
||||
- **E2E**: `scripts/e2e/test-abcip.ps1` — see the *SystemTagBrowse* +
|
||||
*RefreshTagDbWrite* assertions.
|
||||
|
||||
Reference in New Issue
Block a user