Skip to main content

Working-group repositories (spec-repo pull)

The OPC Foundation publishes companion specifications from GitHub repositories built from its specification template: source/<spec>/manifest.json carries the identity, model/*.NodeSet2.xml the model, model/dependencies/ the pinned companion specs it was built against, artifacts/<name>.NodeIds.csv the working group's NodeId table.

spec-repo pull projects such a repository into one self-contained model you can open, lint and edit with the modeler. It never writes into the repository.

opcua-modeler spec-repo pull path/to/OPC40501-MachineTools
# pulled OPC 40501-1 OPC UA for Machine Tools - Part 1: Machine Monitoring and Job Management
# model: model/Opc.Ua.MachineTool.NodeSet2.xml (http://opcfoundation.org/UA/MachineTool/, 1.02.0)
# dependency: http://opcfoundation.org/UA/DI/ 1.04.0 (pinned in the repository)
# dependency: http://opcfoundation.org/UA/Machinery/ 1.03.0 (pinned in the repository)
# ...
# node ids: 533 assigned, 56 retired
# NodeIds.csv: artifacts/Opc.Ua.MachineTool.NodeIds.csv, 589 rows, 0 not in the NodeSet
# output: MachineTool.opcua.yaml
OptionMeaning
<repo>the repository folder (a clone, or a checkout of the template layout)
--spec <shortName>which specification, when the repository publishes several (identity.shortName or the source/ folder name)
-o, --outputthe .opcua.yaml to write; default <shortName>.opcua.yaml in the current folder. A path inside the repository is refused
--declarations private|allsee self-contained models
-f, --forceoverwrite an existing output

What happens

  1. The manifest names the NodeSet and the namespace; both are checked against each other.
  2. The <RequiredModel> chain is resolved from model/dependencies/ first, so the model is read against the exact versions the group pinned, then from the bundled companion specifications.
  3. The NodeSet is reversed into the YAML DSL and packed with the NodeIds of the XML as the symbol table. Nodes the reversed model does not reproduce keep their ids as retired and are listed, so nothing gets renumbered on a later generate.
  4. The group's NodeIds.csv is compared with the NodeSet and any row it holds for a node that is not in the NodeSet is reported.

The output is an ordinary self-contained model: generate --frozen checks it, unpack gives the pair form, and the editor opens it.

What is not there yet

The way back, spec-repo push, which patches only the changed nodes into the repository's NodeSet and appends clause skeletons for new types, is the next story of this epic.