Includes: README explaining purpose / scope / temporary-location framing / format decision, CONTRIBUTING.md with proposed workflow + per-class semver versioning policy + validation commands, format/equipment-class.schema.json defining the shape of a class template (classId, version, displayName, applicability, signals, alarms, optional stateModel), format/tag-definition.schema.json defining the shape of a single canonical signal (name, dataType, category, unit, isArray, accessLevel, writeIdempotent, isHistorized, scaling), format/uns-subtree.schema.json defining the shape of a per-site UNS subtree (enterprise + site + areas + lines), classes/fanuc-cnc.json as the worked pilot class with 16 signals + 3 alarms + suggested state-derivation notes (per OtOpcUa corrections doc D1), uns/example-warsaw-west.json as a worked UNS subtree example, docs/overview.md (what / why / lifecycle / what's NOT in this repo), docs/format-decisions.md (8 numbered decisions covering JSON Schema choice per corrections D2, per-class semver, additive-only minor bumps, _default placeholder reservation, signal-name vs UNS-segment regex distinction, stateModel-as-informational, no per-equipment overrides at this layer, applicability.drivers as OtOpcUa driver enumeration), docs/consumer-integration.md (how OtOpcUa / Redpanda / dbt each integrate). $id URLs in the JSON schemas resolve at the actual current path so validators don't 404. Top-level README adds a row to the Component Detail Files table pointing to schemas/. Corrections doc B2 (schemas-repo dependencies) marked partially RESOLVED with the seed location and a list of what still needs the plan team or cross-team owner to decide (owner team naming, dedicated repo migration, format-decision ratification, FANUC CNC pilot confirmation, CI gate setup, Redpanda + dbt consumer integration plumbing). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
88 lines
5.0 KiB
JSON
88 lines
5.0 KiB
JSON
{
|
|
"$schema": "../format/equipment-class.schema.json",
|
|
"classId": "fanuc-cnc",
|
|
"version": "0.1.0",
|
|
"displayName": "FANUC CNC",
|
|
"description": "FANUC CNC machine tools (mills, lathes, machining centers) accessed via FOCAS2. 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 (e.g. '0i-F'). From cnc_sysinfo()." },
|
|
{ "name": "Version", "category": "Identity", "dataType": "String", "description": "CNC software version. From cnc_sysinfo()." },
|
|
{ "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": "0=STOP, 1=HOLD, 2=START, 3=MSTR. From cnc_statinfo()." },
|
|
{ "name": "Mode", "category": "Status", "dataType": "Int32", "description": "0=MDI, 1=AUTO, 3=EDIT, 4=HANDLE, 5=JOG, 7=REF. From cnc_statinfo()." },
|
|
{ "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()." },
|
|
|
|
{
|
|
"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()." },
|
|
{ "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)." },
|
|
|
|
{ "name": "ActiveAlarmCount", "category": "Alarm", "dataType": "Int32", "description": "Number of active alarms. From cnc_rdalmmsg(). FOCAS2." }
|
|
],
|
|
"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."
|
|
}
|
|
}
|