Equipment-class.schema.json gains an `extends` field for class inheritance — child classes inherit signals, alarms, and stateModel from the parent and can add new ones or override individual entries by name. Convention: `_` prefix on classId marks an abstract base class (e.g. `_base`) intended only to be extended, not assigned directly to equipment via Equipment.EquipmentClassRef. FANUC CNC class updated to extends: "_base"; redundant identity signals (Version, ActiveAlarmCount) removed since they're now in the base; remaining FANUC-specific signals updated with cross-references showing how they feed into the base signals at Layer 3 (RunState → canonical Running/Idle/Faulted derivation; AlarmActive → HasActiveAlarms / HighestActiveAlarmSeverity; PartsCount → TotalCycles; MainProgramNumber → CurrentRecipe). Format-decisions.md adds D9 (rationale for `_base` + `extends` inheritance, with references to OPC 40010 / Part 9 / ISO 22400 / handoff) and D10 (signal `category` drives OPC UA folder placement, per OPC 40010 Identification + Status pattern, with a category-to-folder mapping table). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
92 lines
5.5 KiB
JSON
92 lines
5.5 KiB
JSON
{
|
|
"$schema": "../format/equipment-class.schema.json",
|
|
"classId": "fanuc-cnc",
|
|
"extends": "_base",
|
|
"version": "0.1.0",
|
|
"displayName": "FANUC CNC",
|
|
"description": "FANUC CNC machine tools (mills, lathes, machining centers) accessed via FOCAS2. Extends `_base` for cross-machine identity / state / alarm metadata; adds CNC-specific axis, spindle, program, and PMC signals. Pilot equipment class per OtOpcUa corrections doc D1 — chosen because the FOCAS driver already exposes a fixed pre-defined node hierarchy (lmxopcua/docs/v2/driver-specs.md §7) which is essentially a class template already; this file formalizes it.",
|
|
"vendor": "FANUC",
|
|
"applicability": {
|
|
"drivers": ["Focas"],
|
|
"models": ["0i-F", "0i-D", "30i-B", "31i-B", "32i-B"]
|
|
},
|
|
"signals": [
|
|
{
|
|
"name": "SeriesNumber",
|
|
"category": "Identity",
|
|
"dataType": "String",
|
|
"description": "CNC series read dynamically from the controller (e.g. '0i-F'). From cnc_sysinfo(). May differ from the operator-set Model if firmware reports a different series — useful for catching configuration drift.",
|
|
"isRequired": true
|
|
},
|
|
{ "name": "MaxAxes", "category": "Identity", "dataType": "Int32", "description": "Maximum axes supported by this CNC. From cnc_sysinfo()." },
|
|
{ "name": "AxisCount", "category": "Identity", "dataType": "Int32", "description": "Active axis count. From cnc_rdaxisname()." },
|
|
|
|
{ "name": "RunState", "category": "Status", "dataType": "Int32", "description": "FANUC native run state — 0=STOP, 1=HOLD, 2=START, 3=MSTR. From cnc_statinfo(). Layer 3 derives the canonical Running/Idle/Faulted state (in `_base.stateModel`) primarily from this signal." },
|
|
{ "name": "Mode", "category": "Status", "dataType": "Int32", "description": "0=MDI, 1=AUTO, 3=EDIT, 4=HANDLE, 5=JOG, 7=REF. From cnc_statinfo(). Maps to `_base.OperationMode` enum at Layer 3." },
|
|
{ "name": "MotionState", "category": "Status", "dataType": "Int32", "description": "0=idle, 1=MOTION, 2=DWELL, 3=WAIT. From cnc_statinfo()." },
|
|
{ "name": "EmergencyStop", "category": "Status", "dataType": "Boolean", "description": "From cnc_statinfo()." },
|
|
{ "name": "AlarmActive", "category": "Status", "dataType": "Int32", "description": "Bitmask of active alarm categories. From cnc_statinfo(). Layer 3 derives `_base.HasActiveAlarms` and `_base.HighestActiveAlarmSeverity` from this and cnc_rdalmmsg() detail." },
|
|
|
|
{
|
|
"name": "AxisAbsolutePosition",
|
|
"category": "Position",
|
|
"dataType": "Float64",
|
|
"unit": "mm",
|
|
"isArray": true,
|
|
"arrayDimension": 32,
|
|
"description": "Per-axis absolute position. Indexed by axis number. From cnc_absolute(). FANUC scaled-integer source converted via cnc_getfigure().",
|
|
"scaling": { "method": "DecimalPlaces", "decimalPlaces": 3 }
|
|
},
|
|
{
|
|
"name": "AxisMachinePosition",
|
|
"category": "Position",
|
|
"dataType": "Float64",
|
|
"unit": "mm",
|
|
"isArray": true,
|
|
"arrayDimension": 32,
|
|
"description": "Per-axis machine position. From cnc_machine().",
|
|
"scaling": { "method": "DecimalPlaces", "decimalPlaces": 3 }
|
|
},
|
|
{
|
|
"name": "ActualFeedRate",
|
|
"category": "Velocity",
|
|
"dataType": "Float64",
|
|
"unit": "mm/min",
|
|
"description": "Actual feed rate. From cnc_actf()."
|
|
},
|
|
{
|
|
"name": "SpindleActualSpeed",
|
|
"category": "Velocity",
|
|
"dataType": "Float64",
|
|
"unit": "rpm",
|
|
"isArray": true,
|
|
"arrayDimension": 8,
|
|
"description": "Per-spindle actual speed. From cnc_acts() / cnc_acts2()."
|
|
},
|
|
{
|
|
"name": "SpindleLoad",
|
|
"category": "Process",
|
|
"dataType": "Float64",
|
|
"unit": "%",
|
|
"isArray": true,
|
|
"arrayDimension": 8,
|
|
"description": "Per-spindle load percentage. From cnc_rdspmeter(). FOCAS2."
|
|
},
|
|
|
|
{ "name": "MainProgramNumber", "category": "Process", "dataType": "Int32", "description": "From cnc_rdprgnum(). Source for `_base.CurrentRecipe` at Layer 3 if the site uses program numbers as recipes." },
|
|
{ "name": "RunningProgramNumber", "category": "Process", "dataType": "Int32", "description": "From cnc_rdprgnum()." },
|
|
{ "name": "RunningProgramName", "category": "Process", "dataType": "String", "description": "Full program path/name. From cnc_exeprgname(). FOCAS2." },
|
|
{ "name": "SequenceNumber", "category": "Process", "dataType": "Int32", "description": "Current N-number. From cnc_rdseqnum()." },
|
|
{ "name": "PartsCount", "category": "Counter", "dataType": "Int64", "description": "Parts produced. From cnc_rdparam(6711/6712). Source for `_base.TotalCycles` at Layer 3." }
|
|
],
|
|
"alarms": [
|
|
{ "alarmId": "ps-alarm", "displayName": "Program/Setup Alarm", "severity": "High", "description": "P/S alarm category." },
|
|
{ "alarmId": "ot-alarm", "displayName": "Overtravel Alarm", "severity": "Critical", "description": "OT alarm category — axis overtravel." },
|
|
{ "alarmId": "sv-alarm", "displayName": "Servo Alarm", "severity": "Critical", "description": "Servo subsystem alarm." }
|
|
],
|
|
"stateModel": {
|
|
"states": ["Running", "Idle", "Faulted", "Starved", "Blocked"],
|
|
"derivationNotes": "Derivation lives at Layer 3 (System Platform / Ignition), not in OtOpcUa. Suggested mapping (informational): RunState=2 (START) AND MotionState=1 (MOTION) AND AlarmActive=0 → Running; RunState=0 (STOP) OR RunState=1 (HOLD) → Idle; AlarmActive≠0 OR EmergencyStop=true → Faulted; Starved/Blocked are inferred from upstream/downstream signals not exposed by FOCAS itself."
|
|
}
|
|
}
|