7.9 KiB
otopcua-ablegacy-cli — AB Legacy (PCCC) test client
Ad-hoc probe / read / write / subscribe tool for SLC 500 / MicroLogix 1100 /
MicroLogix 1400 / PLC-5 devices, talking to the same AbLegacyDriver the
OtOpcUa server uses (libplctag PCCC back-end).
Third of four driver test-client CLIs. Shares Driver.Cli.Common with the
others.
Build + run
dotnet run --project src/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.Cli -- --help
Common flags
| Flag | Default | Purpose |
|---|---|---|
-g / --gateway |
required | Canonical ab://host[:port]/cip-path |
-P / --plc-type |
Slc500 |
Slc500 / MicroLogix / Plc5 / LogixPccc |
--timeout-ms |
5000 |
Per-operation timeout — see precedence note below |
--retries |
0 |
Retry count on transient BadCommunicationError (PR 9 / #252) |
--verbose |
off | Serilog debug output |
Family ↔ CIP-path cheat sheet:
- SLC 5/05 / PLC-5 —
1,0 - MicroLogix 1100 / 1400 — empty path (
ab://host/) — they use direct EIP with no backplane - LogixPccc —
1,0(Logix controller accessed via the PCCC compatibility layer; rare)
Per-device timeout / retry tuning (#252, PR 9)
The CLI's --timeout-ms is the driver-wide default when launched as a
one-shot test client. In production (server-side, multi-device deployment)
each AbLegacyDeviceOptions row carries its own optional Timeout /
Retries that override the driver-wide value.
Precedence (highest → lowest): per-device override → driver-wide default → hard-coded fallback (2000 ms / 0 retries).
Tuning cheat sheet — start here, measure, then trim:
| Family | Recommended Timeout |
Notes |
|---|---|---|
| SLC 5/01 (RS-232 / DH+ bridge) | 5000 ms | Slowest of the bunch; serial round-trip plus DH+ hop |
| SLC 5/02 / 5/03 (DH+) | 3000 ms | Bridged Ethernet → DH+ adds ~1 s |
| SLC 5/04 / 5/05 (Ethernet) | 2000 ms | Fastest of the SLC family — direct EIP/PCCC |
| MicroLogix 1100 / 1400 | 3000 ms | Single-CPU, slow scan; no backplane |
| PLC-5 (Ethernet I/F) | 2500 ms | Comparable to SLC 5/05 over EIP |
| LogixPccc compat layer | 2000 ms | Logix CPU is fast; PCCC layer is the floor |
A small --retries 1 (or 2 for slow chassis) is generally safe — the retry
loop only fires on transient BadCommunicationError; terminal errors
(BadNodeIdUnknown, BadTypeMismatch, …) surface on the first attempt.
PCCC address primer
File letters imply data type; type flag still required so the CLI knows how to
parse your --value.
| File | Type | CLI --type |
|---|---|---|
N |
signed int16 | Int |
F |
float32 | Float |
B |
bit-packed (B3:0/3 addresses bit 3 of word 0) |
Bit |
L |
long int32 (SLC 5/05+ only) | Long |
A |
analog int (semantically like N) | AnalogInt |
ST |
ASCII string (82-byte + length header) | String |
T |
timer sub-element (T4:0.ACC / .PRE / .EN / .DN) |
TimerElement |
C |
counter sub-element (C5:0.ACC / .PRE / .CU / .CD / .DN) |
CounterElement |
R |
control sub-element (R6:0.LEN / .POS / .EN / .DN / .ER) |
ControlElement |
Commands
probe
# SLC 5/05 — default probe address N7:0
otopcua-ablegacy-cli probe -g ab://192.168.1.20/1,0
# MicroLogix 1100 — status file first word
otopcua-ablegacy-cli probe -g ab://192.168.1.30/ -P MicroLogix -a S:0
read
# Integer
otopcua-ablegacy-cli read -g ab://192.168.1.20/1,0 -a N7:10 -t Int
# Float
otopcua-ablegacy-cli read -g ab://192.168.1.20/1,0 -a F8:0 -t Float
# Bit-within-word
otopcua-ablegacy-cli read -g ab://192.168.1.20/1,0 -a B3:0/3 -t Bit
# Long (SLC 5/05+)
otopcua-ablegacy-cli read -g ab://192.168.1.20/1,0 -a L19:0 -t Long
# Timer ACC
otopcua-ablegacy-cli read -g ab://192.168.1.20/1,0 -a T4:0.ACC -t TimerElement
# Diagnostic counter (PR ablegacy-10 / #253). The seven _Diagnostics/<name>
# addresses live alongside user tags — short-circuit serves them straight from
# the in-process counter store, so no PCCC frame is sent to the PLC.
otopcua-ablegacy-cli read -g ab://192.168.1.20/1,0 --address _Diagnostics/RequestCount
The diagnostic surface auto-emits per device — no config required. See
docs/drivers/AbLegacy-Diagnostics.md for the full counter table + reset
semantics + collision-rejection rules.
write
otopcua-ablegacy-cli write -g ab://192.168.1.20/1,0 -a N7:10 -t Int -v 42
otopcua-ablegacy-cli write -g ab://192.168.1.20/1,0 -a F8:0 -t Float -v 3.14
otopcua-ablegacy-cli write -g ab://192.168.1.20/1,0 -a B3:0/3 -t Bit -v on
Writes to timer / counter / control sub-elements land at the wire level but the PLC's runtime semantics (EN/DN edge-triggering, preset reload) are PLC-managed — use with caution.
subscribe
otopcua-ablegacy-cli subscribe -g ab://192.168.1.20/1,0 -a N7:10 -t Int -i 500
Deadband
PR 8 — per-tag absolute / percent change filter on top of the polled subscription. The driver
caches the last published value per tag and suppresses OnDataChange notifications until the
new sample crosses the configured threshold.
| Flag | Effect |
|---|---|
--deadband-absolute <value> |
Suppress until ` |
--deadband-percent <value> |
Suppress until ` |
Booleans bypass the filter entirely (every transition publishes); strings + status changes always publish; first-seen always publishes; both flags set → either passing triggers a publish (Kepware-style logical OR).
# Float — drop sub-0.5 jitter from the noisy load-cell address.
otopcua-ablegacy-cli subscribe -g ab://192.168.1.20/1,0 -a F8:0 -t Float -i 500 `
--deadband-absolute 0.5
# Integer — only fire on >= 5% deviation from the last reported value.
otopcua-ablegacy-cli subscribe -g ab://192.168.1.20/1,0 -a N7:10 -t Int -i 500 `
--deadband-percent 5
Array reads
PR 7 — one PCCC frame can carry up to ~120 words. Address an array tag with either the
Rockwell-native ,N suffix or the libplctag-native [N] suffix on the word number; both
forms canonicalise to [N] when the driver hands the tag to libplctag, and the parser
caps N at 120.
# Rockwell `,N` form — "10 consecutive words starting at N7:0"
otopcua-ablegacy-cli read -g ab://192.168.1.20/1,0 -a "N7:0,10" -t Int
# libplctag `[N]` form — same wire result
otopcua-ablegacy-cli read -g ab://192.168.1.20/1,0 -a "N7:0[10]" -t Int
# Float / Long arrays — same suffix syntax, narrower frame ceiling on Float (~60 elements)
# and Long (~60 elements) because each element is 4 bytes vs Int's 2.
otopcua-ablegacy-cli read -g ab://192.168.1.20/1,0 -a "F8:0,4" -t Float
otopcua-ablegacy-cli read -g ab://192.168.1.20/1,0 -a "L19:0,4" -t Long
# --array-length override — pin the element count from config rather than the address
# suffix. Wins over the parsed `,N` / `[N]` value when both are set; useful for keeping the
# address string compact while bumping the element count from a tags config file.
otopcua-ablegacy-cli read -g ab://192.168.1.20/1,0 -a "N7:0" --array-length 10 -t Int
Array tags reject sub-element references (T4:0,5.ACC) and bit suffixes (N7:0,10/3) at
parse time — both combinations are semantically meaningless against a contiguous block.
For B-files the Rockwell convention is "one BOOL per word, not per bit": B3:0,10
returns bool[10] (one per word's non-zero state), not bool[160].
Known caveat — ab_server upstream gap
The integration-fixture ab_server Docker container accepts TCP but its PCCC
dispatcher doesn't actually respond — see
tests/...AbLegacy.IntegrationTests/Docker/README.md.
Point --gateway at real hardware or an RSEmulate 500 box for end-to-end
wire-level validation. The CLI itself is correct regardless of which endpoint
you target.