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>
82 lines
6.6 KiB
Markdown
82 lines
6.6 KiB
Markdown
# schemas — Canonical OT Equipment Definitions
|
||
|
||
> **Status**: DRAFT — initial seed contributed by the OtOpcUa team (`lmxopcua/docs/v2/acl-design.md`, `lmxopcua/docs/v2/plan.md` decisions #112, #115, corrections doc D1+D2). **Ownership of this content is TBD** — should be assigned to a cross-team authority since it's consumed by OT and IT systems alike. The future owner team should treat this seed as a starting point, not a finished spec.
|
||
>
|
||
> **Temporary location**: this seed lives at `3yearplan/schemas/` as a sub-tree of the 3-year-plan repo because Gitea's push-to-create is disabled and creating the dedicated `schemas` repo requires a manual UI step. Once the dedicated repo is created (proposed: `gitea.dohertylan.com/dohertj2/schemas`) and an owner team is named, this content should migrate over and references update accordingly. Until then, treat this directory as the canonical location for the seed.
|
||
|
||
## Purpose
|
||
|
||
Single source of truth for the org's canonical OT equipment definitions:
|
||
|
||
1. **UNS hierarchy** — the per-site Unified Namespace subtree (Enterprise / Site / Area / Line / Equipment) per the 3-year-plan handoff §UNS Naming Hierarchy
|
||
2. **Equipment-class templates** — per-class declarations of which raw signals each equipment type exposes (FANUC CNCs surface these; Modbus PLCs surface those; etc.)
|
||
3. **Type vocabulary** — the canonical machine-state values (`Running` / `Idle` / `Faulted` / `Starved` / `Blocked`) and any other shared enumerations consumers need
|
||
|
||
## Who consumes this
|
||
|
||
Three surfaces per the 3-year-plan handoff §"Canonical Model Integration":
|
||
|
||
| Consumer | How |
|
||
|----------|-----|
|
||
| **OtOpcUa equipment namespace** | At deploy/config time, OtOpcUa nodes fetch the equipment-class template referenced by `Equipment.EquipmentClassRef` and use it to validate the operator-configured tag set. Drift = config validation error |
|
||
| **Redpanda topics + Protobuf schemas** | Equipment-class templates derive Protobuf message definitions for canonical events (`equipment.state.transitioned`, etc.) |
|
||
| **dbt curated layer in Snowflake** | Same templates derive column definitions and dimension tables for the curated analytics model |
|
||
|
||
OtOpcUa is one consumer of three. Decisions about format, structure, and naming live with the schemas-repo owner team (TBD), not with any one consumer.
|
||
|
||
## Format
|
||
|
||
**JSON Schema (Draft 2020-12) authored in this repo; Protobuf code-generated for wire serialization where needed** (per OtOpcUa corrections doc D2 recommendation, blessed by the OtOpcUa team but pending schemas-repo team review).
|
||
|
||
Why JSON Schema as the authoring format:
|
||
- Idiomatic for .NET (System.Text.Json + JsonSchema.Net) — OtOpcUa reads templates with no extra dependencies
|
||
- Idiomatic for CI tooling (every CI runner can `jq` / validate JSON Schema without extra toolchain)
|
||
- Supports validation at multiple layers: operator-visible Admin UI errors in OtOpcUa, schemas-repo CI gates, downstream consumer runtime validation
|
||
- Better authoring experience than Protobuf (binary format, .proto compiler, poor merge story)
|
||
- Where wire-format efficiency matters (Redpanda events), code-generate Protobuf from the JSON Schema source. One-way derivation is simpler than bidirectional sync.
|
||
|
||
## Structure
|
||
|
||
```
|
||
schemas/
|
||
├── README.md This file
|
||
├── CONTRIBUTING.md How to add a new class, validate, PR process
|
||
├── format/ JSON Schemas defining the format of everything below
|
||
│ ├── equipment-class.schema.json Shape of an equipment-class template
|
||
│ ├── uns-subtree.schema.json Shape of a per-site UNS subtree definition
|
||
│ └── tag-definition.schema.json Shape of an individual tag declaration inside a template
|
||
├── classes/ Equipment-class templates
|
||
│ └── fanuc-cnc.json Pilot class per OtOpcUa corrections D1
|
||
├── uns/ Per-site UNS subtree definitions
|
||
│ └── example-warsaw-west.json Worked example
|
||
└── docs/
|
||
├── overview.md What this repo is, who uses it, lifecycle
|
||
├── format-decisions.md Why JSON Schema, structure rationale, Protobuf derivation
|
||
└── consumer-integration.md How each of the 3 consumers integrates
|
||
```
|
||
|
||
## Lifecycle
|
||
|
||
1. **Author** — humans edit JSON files in this repo, validated against the schemas in `format/` by the CI gate
|
||
2. **Publish** — merging to `main` makes the new content the authoritative version; semver tag on each release
|
||
3. **Consume** — each consumer pulls a specific tagged version (or `main` for staging environments) and integrates per `docs/consumer-integration.md`
|
||
|
||
The current state has no consumers actively reading from this repo — content is seed-only. First wiring happens in OtOpcUa Phase 1+ when `Equipment.EquipmentClassRef` validation lands (see `lmxopcua/docs/v2/plan.md` decision #112).
|
||
|
||
## Open Questions
|
||
|
||
Owner-team-decisions (not for OtOpcUa or any single consumer to make alone):
|
||
|
||
- **Repo ownership and review process**: who owns this repo? PR review SLA? Format changes need who to sign off?
|
||
- **Versioning policy**: semver per release? Per-class versioning vs whole-repo versioning? How do consumers pin versions?
|
||
- **Backward-compatibility policy**: when a class adds a new required signal, do all existing equipment in OtOpcUa's central config DB need to be updated atomically? Or graceful degradation?
|
||
- **Cross-class shared types**: how does a `Position` measurement (used by both FANUC CNC and a Beckhoff axis) avoid duplicate definitions?
|
||
- **Pilot class scope**: FANUC CNC chosen per OtOpcUa corrections D1 because FOCAS already has a fixed pre-defined hierarchy. Confirm with the schemas-repo team that this is the right starting class.
|
||
- **Enterprise shortname** (currently `ent` placeholder) — the UNS subtree definitions reference an Enterprise segment; the canonical value comes from organizational naming authority.
|
||
|
||
## References
|
||
|
||
- 3-year-plan handoff: `gitea.dohertylan.com/dohertj2/3yearplan` → `handoffs/otopcua-handoff.md` §"UNS Naming Hierarchy" + §"Canonical Model Integration" + §"Digital Twin Touchpoints"
|
||
- OtOpcUa corrections doc: `gitea.dohertylan.com/dohertj2/3yearplan` → `handoffs/otopcua-corrections-2026-04-17.md` §B2 (schemas-repo dependencies) + §D1 (pilot class) + §D2 (format)
|
||
- OtOpcUa v2 plan: `gitea.dohertylan.com/dohertj2/lmxopcua` → `docs/v2/plan.md` decisions #108–115 + §"UNS naming hierarchy"
|