8.9 KiB
FOCAS deployment guide
Per-driver runbook for deploying the FANUC FOCAS driver. See
docs/drivers/FOCAS.md for the per-feature
reference and focas-version-matrix.md for
the per-CNC-series capability surface.
Operator config-knob cheat sheet
| Knob | Where | Default | Notes |
|---|---|---|---|
Devices[].HostAddress |
FocasDriverOptions.Devices |
— | focas://{ip}[:{port}] |
Devices[].Series |
FocasDriverOptions.Devices |
Unknown |
Drives per-series range validation in FocasCapabilityMatrix. |
Devices[].OverrideParameters |
FocasDriverOptions.Devices |
null |
MTB-specific parameter numbers for Feed/Rapid/Spindle/Jog overrides. null suppresses the Override/ subtree. |
Probe.Enabled |
FocasDriverOptions.Probe |
true |
Background reachability probe. |
Probe.Interval |
FocasDriverOptions.Probe |
00:00:05 |
Probe cadence. |
FixedTree.ApplyFigureScaling |
FocasDriverOptions.FixedTree |
true |
Divide position values by 10^decimal-places (issue #262). |
AlarmProjection.Mode |
FocasDriverOptions.AlarmProjection |
ActiveOnly |
ActiveOnly keeps today's behaviour. ActivePlusHistory polls cnc_rdalmhistry on connect + on HistoryPollInterval ticks (issue #267, plan PR F3-a). |
AlarmProjection.HistoryPollInterval |
FocasDriverOptions.AlarmProjection |
00:05:00 |
Cadence of the history poll. Operator dashboards run the default; high-frequency rigs can drop to 30 s. |
AlarmProjection.HistoryDepth |
FocasDriverOptions.AlarmProjection |
100 |
Most-recent-N ring-buffer entries pulled per poll. Hard-capped at 250 so misconfigured values can't blast the wire session. |
Sample appsettings.json snippet for ActivePlusHistory
{
"Drivers": {
"FOCAS": {
"Devices": [
{ "HostAddress": "focas://10.0.0.5:8193", "Series": "Series30i" }
],
"AlarmProjection": {
"Mode": "ActivePlusHistory",
"HistoryPollInterval": "00:05:00",
"HistoryDepth": 100
}
}
}
}
The history projection emits each unseen entry through
IAlarmSource.OnAlarmEvent with SourceTimestampUtc set from the CNC's
reported wall-clock — keep CNC clocks on UTC so the dedup key
(OccurrenceTime, AlarmNumber, AlarmType) stays stable across DST
transitions.
Write safety — issue #269 (PARAM/MACRO, F4-b) + issue #270 (PMC, F4-c)
The FOCAS driver supports cnc_wrparam, cnc_wrmacro, and pmc_wrpmcrng
writes behind multiple independent opt-ins. A misdirected parameter write
can put the CNC in a bad state; a misdirected PMC write can move motion or
latch a feedhold. The runbook below MUST be followed before flipping any
of the granular kill switches on.
Operator pre-checks (every deployment, every change)
- CNC must be in MDI mode. Most parameter writes fail with
EW_PASSWD(surfaces asBadUserAccessDenied) unless the CNC is in MDI. The server-side write returns immediately with the access-denied status; no value reaches the wire. - Parameter-write switch enabled on the CNC pendant. Even in MDI mode
protected parameters require the operator to physically enable the
parameter-write switch. Without it
cnc_wrparamreturnsEW_PASSWD. Plan PR F4-d will land an OPC UA-side unlock workflow; today the only path is the pendant. - Verify each tag's address against the FANUC manual. Ranges vary per
CNC series; the
focas-version-matrixcapability matrix rejects out-of-range numbers at startup, but address-vs-meaning is the operator's job. - Dry run with
Writable = truebutWrites.AllowParameter = false. Staged opt-in catches mis-mapped tags: every PARAM write returnsBadNotWritableuntil you flip the granular flag, so you can confirm the tag list before any wire write fires.
PMC pre-checks (in addition to the above) — F4-c
PMC writes have a higher blast radius than PARAM/MACRO writes because PMC
is the ladder's working memory — bits in R/G/F/D directly drive servo
enables, feedhold latches, and safety interlocks. Before flipping
Writes.AllowPmc on:
- E-stop verified live + reachable. The first PMC write of a session should be issued with the operator's hand on the e-stop. PMC writes bypass the ladder's normal MDI-mode protections; a misdirected bit can move motion the moment it lands on the wire.
- Machine in JOG mode (or equivalent low-energy mode). Auto / MEM modes interpret PMC state immediately; JOG / MDI surface symptoms slowly enough that the e-stop is the recovery path. Never issue the first PMC write of a deployment in Auto.
- Audit the PMC tag list against the ladder print-out.
R100.3on one machine is "homing complete"; on another it's "feedhold released". The driver has no way to distinguish — the ladder source is the only ground truth. - Bit writes are read-modify-write — see
docs/drivers/FOCAS.md"PMC bit-write read-modify-write semantics".pmc_wrpmcrngis byte-addressed; the driver reads the parent byte first, masks the target bit, and writes the byte back. Concurrent ladder writes to the same byte create a small race window. Coordinate through a ladder-side handshake when this matters. - Dry run with
Writable = truebutWrites.AllowPmc = false. Same staged-opt-in pattern as PARAM/MACRO — confirm tag mapping before any PMC byte hits the wire.
LDAP group requirements
Per docs/security.md the server-layer ACL maps
SecurityClassification to LDAP groups. Post-F4-b:
| Tag kind | LDAP group required |
|---|---|
PARAM:N (writable) |
WriteConfigure — heaviest write tier; matches commissioning roles |
MACRO:N (writable) |
WriteOperate — standard HMI recipe / setpoint group |
| PMC R/G/F (writable) | WriteOperate |
| Read-only | ReadOnly |
Per the feedback_acl_at_server_layer design note, the FOCAS driver
declares the classification but does NOT enforce it; DriverNodeManager
applies the gate before the driver's WriteAsync ever runs. A user
without WriteConfigure who attempts a PARAM: write gets
BadUserAccessDenied from the server with no driver-level audit entry —
the OPC UA layer's audit log catches it.
Audit-log expectations
Every successful write produces:
- An OPC UA AuditWriteEvent (server layer — see
docs/security.md"Audit logging"). - A FOCAS driver-level Serilog entry tagged
Driver=FOCAS DriverInstanceId=... TagName=... Address=... ResultStatus=.... - A
Writes/LastWriteAtandWrites/LastWriteStatusdiagnostic counter refresh on the device'sDiagnostics/fixed-tree node (planned; populated as F4-c lands).
Failures to write (BadUserAccessDenied, BadCommunicationError, etc.)
produce the same audit entries with the failure status code so a
post-incident reviewer sees the same shape regardless of whether the write
succeeded.
Audit PMC writes specifically. Because PMC writes have the highest blast
radius of the three write kinds, ops should set up a saved-search /
dashboard query for Driver=FOCAS + Address matching the PMC letter
prefixes (R*, G*, F*, D*, Y*, etc.) and review on the same
cadence as ladder change reviews. A spike in PMC write rate or a write
to an address outside the audited tag list is the leading indicator of a
misconfigured client or compromised credential.
Granular config example
{
"Drivers": {
"FOCAS": {
"Devices": [
{ "HostAddress": "focas://10.0.0.5:8193", "Series": "Series30i" }
],
"Writes": {
"Enabled": true,
"AllowMacro": true, // recipe / setpoint writes — operator role
"AllowParameter": false, // commissioning only — keep locked except during planned work
"AllowPmc": false // PMC writes — keep locked unless the deployment specifically needs them
},
"Tags": [
{ "Name": "Recipe.PartCount", "DeviceHostAddress": "focas://10.0.0.5:8193",
"Address": "MACRO:500", "DataType": "Int32",
"Writable": true, "WriteIdempotent": true },
{ "Name": "MaxFeedrate", "DeviceHostAddress": "focas://10.0.0.5:8193",
"Address": "PARAM:1815", "DataType": "Int32",
"Writable": false /* keep read-only until commissioning window */ },
{ "Name": "OperatorRequest", "DeviceHostAddress": "focas://10.0.0.5:8193",
"Address": "R100.3", "DataType": "Bit",
"Writable": false /* keep PMC read-only until ladder handshake reviewed */ }
]
}
}
}
Flipping AllowParameter / AllowPmc on for the commissioning window
(and back off afterward) is the recommended deployment cadence — the
granular kill switches are lightweight runtime toggles, not config-DB
redeploys. PMC in particular should default OFF in production and only
flip on for windows where the ladder team has signed off on the write
path.