{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://gitea.dohertylan.com/dohertj2/3yearplan/raw/branch/main/schemas/format/equipment-class.schema.json", "title": "Equipment-Class Template", "description": "Declares the canonical raw signal vocabulary for an equipment class. Consumed by OtOpcUa (validates per-equipment tag config), Redpanda (derives Protobuf event schemas), and dbt (derives column definitions for the curated layer).", "type": "object", "required": ["classId", "version", "displayName", "signals"], "additionalProperties": false, "properties": { "classId": { "type": "string", "pattern": "^[a-z0-9-_]{1,64}$", "description": "Stable logical ID for the class. Lowercase, hyphens, underscores allowed. Once published, never changes — clients pin to it. Convention: `_` prefix indicates an abstract base class (e.g. `_base`) intended only to be extended, not used directly on equipment." }, "extends": { "type": ["string", "null"], "pattern": "^[a-z0-9-_]{1,64}$", "description": "Optional parent class to inherit from. Inherited signals, alarms, and stateModel are merged into this class — the child can add new ones and override individual entries by `name`. The `_base` class (which every equipment template should extend) provides the universal cross-machine metadata (identity, state, alarms, optional production context)." }, "version": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$", "description": "Semver. Major bump = breaking change; minor = additive non-breaking; patch = doc/clarification only." }, "displayName": { "type": "string", "minLength": 1, "maxLength": 128, "description": "Human-readable name (e.g. 'FANUC CNC')." }, "description": { "type": "string", "maxLength": 1024, "description": "Optional longer description." }, "vendor": { "type": "string", "maxLength": 64, "description": "Vendor or family (e.g. 'FANUC', 'Allen-Bradley', 'Siemens')." }, "applicability": { "type": "object", "description": "When this class applies. Optional; omit for vendor-agnostic classes.", "properties": { "drivers": { "type": "array", "items": { "type": "string", "enum": ["Galaxy", "ModbusTcp", "AbCip", "AbLegacy", "S7", "TwinCat", "Focas", "OpcUaClient"] }, "description": "Which OtOpcUa drivers can populate equipment of this class." }, "models": { "type": "array", "items": { "type": "string" }, "description": "Free-text model identifiers (e.g. '0i-F', '30i-B' for FANUC; '1756-L84E' for Logix)." } }, "additionalProperties": false }, "signals": { "type": "array", "minItems": 1, "items": { "$ref": "tag-definition.schema.json" }, "description": "Required signals every equipment of this class must expose. Operator-configured tags in OtOpcUa are validated against this list — missing required signals = config error; extra signals are allowed (operator-extensible)." }, "alarms": { "type": "array", "items": { "type": "object", "required": ["alarmId", "displayName", "severity"], "additionalProperties": false, "properties": { "alarmId": { "type": "string", "pattern": "^[a-z0-9-]{1,64}$" }, "displayName": { "type": "string", "minLength": 1, "maxLength": 128 }, "severity": { "type": "string", "enum": ["Low", "Medium", "High", "Critical"] }, "description": { "type": "string", "maxLength": 1024 } } }, "description": "Optional canonical alarm definitions for this class." }, "stateModel": { "type": "object", "description": "Optional declaration of how this class's raw signals derive into the canonical machine-state vocabulary at Layer 3 (System Platform / Ignition). Informational — derivation lives at Layer 3, not in OtOpcUa.", "properties": { "states": { "type": "array", "items": { "type": "string", "enum": ["Running", "Idle", "Faulted", "Starved", "Blocked", "Changeover", "Maintenance", "Setup"] } }, "derivationNotes": { "type": "string", "maxLength": 2048 } }, "additionalProperties": false } } }