6.3 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, plan PR F4-b
The FOCAS driver supports cnc_wrparam and cnc_wrmacro writes behind
multiple independent opt-ins. A misdirected parameter write can put the
CNC in a bad state, so the runbook below MUST be followed before flipping
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.
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.
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
},
"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 */ }
]
}
}
}
Flipping AllowParameter on for the commissioning window (and back off
afterward) is the recommended deployment cadence — the granular kill
switch is a lightweight runtime toggle, not a config-DB redeploy.