Files
lmxopcua/docs/Driver.FOCAS.Cli.md
Joseph Doherty 21e0fdd4cd Docs audit — fill gaps so the top-level docs/ reference matches shipped code
Audit of docs/ against src/ surfaced shipped features without current-reference
coverage (FOCAS CLI, Core.Scripting+VirtualTags, Core.ScriptedAlarms,
Core.AlarmHistorian), an out-of-date driver count + capability matrix, ADR-002's
virtual-tag dispatch not reflected in data-path docs, broken cross-references,
and OpcUaServerReqs declaring OPC-020..022 that were never scoped. This commit
closes all of those so operators + integrators can stay inside docs/ without
falling back to v2/implementation/.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 09:42:42 -04:00

5.4 KiB

otopcua-focas-cli — Fanuc FOCAS test client

Ad-hoc probe / read / write / subscribe tool for Fanuc CNCs via the FOCAS/2 protocol. Uses the same FocasDriver the OtOpcUa server does — PMC R/G/F file registers, axis bits, parameters, and macro variables — all through FocasAddressParser syntax.

Sixth of the driver test-client CLIs, added alongside the Tier-C isolation work tracked in task #220.

Architecture note

FOCAS is a Tier-C driver: Fwlib32.dll is a proprietary 32-bit Fanuc library with a documented habit of crashing its hosting process on network errors. The target runtime deployment splits the driver into an in-process FocasProxyDriver (.NET 10 x64) and an out-of-process Driver.FOCAS.Host (.NET 4.8 x86 Windows service) that owns the DLL — see v2/implementation/focas-isolation-plan.md and v2/implementation/phase-6-1-resilience-and-observability.md for topology + supervisor / respawn / back-pressure design.

The CLI skips the proxy and loads FocasDriver directly (via FwlibFocasClientFactory, which P/Invokes Fwlib32.dll in the CLI's own process). There is no public simulator for FOCAS; a meaningful probe requires a real CNC + a licensed Fwlib32.dll on PATH (or next to the executable). On a dev box without the DLL, every wire call surfaces as BadCommunicationError — still useful as a "CLI wire-up is correct" signal.

Build + run

dotnet build src/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Cli
dotnet run --project src/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Cli -- --help

Or publish a self-contained binary:

dotnet publish src/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Cli -c Release -o publish/focas-cli
publish/focas-cli/otopcua-focas-cli.exe --help

Common flags

Every command accepts:

Flag Default Purpose
-h / --cnc-host required CNC IP address or hostname
-p / --cnc-port 8193 FOCAS TCP port (FOCAS-over-EIP default)
-s / --series Unknown CNC series — Unknown / Zero_i_D / Zero_i_F / Zero_i_MF / Zero_i_TF / Sixteen_i / Thirty_i / ThirtyOne_i / ThirtyTwo_i / PowerMotion_i
--timeout-ms 2000 Per-operation timeout
--verbose off Serilog debug output

Addressing

FocasAddressParser syntax — the same format the server + FocasTagDefinition use. Common shapes:

Address Meaning
R100 PMC R-file word register 100
X0.0 PMC X-file bit 0 of byte 0
G50.3 PMC G-file bit 3 of byte 50
F1.4 PMC F-file bit 4 of byte 1
PARAM:1815/0 Parameter 1815, axis 0
MACRO:500 Macro variable 500

Data types

Bit, Byte, Int16, Int32, Float32, Float64, String. Default is Int16 (matches PMC R-file word width).

Commands

probe — is the CNC reachable?

Opens a FOCAS session, reads one sample address, prints driver health.

# Default: read R100 as Int16
otopcua-focas-cli probe -h 192.168.1.50

# Explicit series + address
otopcua-focas-cli probe -h 192.168.1.50 -s ThirtyOne_i --address R200 --type Int16

read — single address

# PMC R-file word
otopcua-focas-cli read -h 192.168.1.50 -a R100 -t Int16

# PMC X-bit
otopcua-focas-cli read -h 192.168.1.50 -a X0.0 -t Bit

# Parameter (axis 0)
otopcua-focas-cli read -h 192.168.1.50 -a PARAM:1815/0 -t Int32

# Macro variable
otopcua-focas-cli read -h 192.168.1.50 -a MACRO:500 -t Float64

write — single value

Values parse per --type with invariant culture. Booleans accept true / false / 1 / 0 / yes / no / on / off.

otopcua-focas-cli write -h 192.168.1.50 -a R100 -t Int16 -v 42
otopcua-focas-cli write -h 192.168.1.50 -a G50.3 -t Bit -v on
otopcua-focas-cli write -h 192.168.1.50 -a MACRO:500 -t Float64 -v 3.14

PMC G/R writes land on a running machine — be careful which file you hit. Parameter writes may require the CNC to be in MDI mode with the parameter-write switch enabled.

Writes are non-idempotent by default — a timeout after the CNC already applied the write will NOT auto-retry (plan decisions #44 + #45).

subscribe — watch an address until Ctrl+C

FOCAS has no push model; the shared PollGroupEngine handles the tick loop.

otopcua-focas-cli subscribe -h 192.168.1.50 -a R100 -t Int16 -i 500

Output format

Identical to the other driver CLIs via SnapshotFormatter:

  • probe / read emit a multi-line block: Tag / Value / Status / Source Time / Server Time. probe prefixes it with CNC, Series, Health, and Last error lines.
  • write emits one line: Write <address>: 0x... (Good | BadCommunicationError | …).
  • subscribe emits one line per change: [HH:mm:ss.fff] <address> = <value> (<status>).

Typical workflows

"Is the CNC alive?"probe.

"Does my parameter write land?"write + read back against the same address. Check the parameter-write switch + MDI mode if the write fails.

"Why did this macro flip?"subscribe to the macro, let the operator reproduce the cycle, watch the HH:mm:ss.fff timeline.

"Is the Fwlib32 DLL wired up?"probe against any host. A DllNotFoundException surfacing as BadCommunicationError with a matching Last error line means the driver is loading but the DLL is missing; anything else means a transport-layer problem.