diff --git a/CLAUDE.md b/CLAUDE.md index aa73ae14..27a9d722 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -154,3 +154,5 @@ dotnet run --project src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI -- subscribe -u opc ``` Address pickers in AdminUI support live browse for OpcUaClient and Galaxy drivers — see `docs/plans/2026-05-28-driver-browsers-design.md`. + +The AdminUI's global **UNS** page (`/uns`) is the single surface for managing the unified namespace fleet-wide (Area → Line → Equipment → Tag/VirtualTag), replacing the old per-cluster UNS/Equipment/Tags tabs. See `docs/Uns.md`. diff --git a/docs/README.md b/docs/README.md index b240f293..a05013e3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -59,6 +59,7 @@ For Modbus / S7 / AB CIP / AB Legacy / TwinCAT / FOCAS / OPC UA Client specifics |-----|--------| | [Configuration.md](Configuration.md) | Live appsettings + environment-variable reference (current state) | | [Configuration.md](v1/Configuration.md) | appsettings bootstrap + Config DB + Admin UI draft/publish (v1 archive — `OTOPCUA_GALAXY_*` env vars now live in mxaccessgw config) | +| [Uns.md](Uns.md) | The global `/uns` master tree — manage Area/Line/Equipment/Tag/VirtualTag fleet-wide; replaces the per-cluster UNS/Equipment/Tags tabs | | [security.md](security.md) | Transport security profiles, LDAP auth, ACL trie, role grants, OTOPCUA0001 analyzer | | [Redundancy.md](Redundancy.md) | `RedundancyCoordinator`, `ServiceLevelCalculator`, apply-lease, Prometheus metrics | | [Reservations.md](Reservations.md) | Fleet-wide ZTag / SAPID external-ID reservations — publish-time claim, release flow | diff --git a/docs/Uns.md b/docs/Uns.md new file mode 100644 index 00000000..4c3ec1de --- /dev/null +++ b/docs/Uns.md @@ -0,0 +1,98 @@ +# UNS — Global Unified-Namespace Management + +The **UNS** page (`/uns` in the AdminUI) is the single surface for managing +the Unified Namespace across the whole fleet. It replaces the old +per-cluster **UNS**, **Equipment**, and **Tags** tabs and the standalone +virtual-tags list — those have been removed; everything now lives in one +global master tree. + +## The tree + +The page shows every layer of the UNS as one expandable tree: + +``` +Enterprise (read-only grouping — ServerCluster.Enterprise) +└─ Site / Cluster (read-only grouping — a ServerCluster row) + └─ Area (editable — UnsArea) + └─ Line (editable — UnsLine) + └─ Equipment (editable — Equipment) + ├─ Tag (editable — equipment-bound Tag) + └─ Virtual tag (editable — VirtualTag) +``` + +**Enterprise and Site/Cluster are read-only here.** They are derived from +columns on the cluster record, not entities of their own, so you create and +configure clusters on the **Clusters** pages (`/clusters`). On a cluster row +the **⚙ settings** link jumps to that cluster. Editable UNS entities start +at **Area**. + +Count badges next to a node show how many direct children it has (for +equipment, the combined tag + virtual-tag count). + +### Navigating + +- **Expand all / Collapse all** toggle the structural levels. Equipment + nodes are left collapsed by Expand-all because their tags/virtual-tags are + **lazy-loaded** — they fetch on first expand (you'll see a brief spinner). +- **Filter by name** does a case-insensitive substring match on the names of + a node's direct children. + +## Creating and editing + +Every editable row has inline actions; clicking one opens a modal: + +| Node | Actions | +|---|---| +| Cluster | **+ Area** | +| Area | **+ Line**, Edit, Delete | +| Line | **+ Equipment**, Edit, Delete | +| Equipment | **+ Tag**, **+ Virtual tag**, Edit, Delete | +| Tag / Virtual tag | Edit, Delete | + +A **+ Child** action pre-fills the parent for you (e.g. **+ Line** on an +area opens the Line modal with that area already selected). Build a branch +top-down: Area → Line → Equipment → Tag / Virtual tag. + +### Served-by cluster + +An area's **cluster assignment is its "served-by" cluster** — the cluster +node that runs it. It's set when you create the area (under a cluster) and +changed by editing the area's cluster in the Area modal, which moves the +whole branch. There is no separate "served-by" concept and no migration — +it is simply `UnsArea.ClusterId`. + +### Tags vs. Galaxy / SystemPlatform tags + +Tags created here are **equipment-bound** and require a driver instance. +The driver list in the Tag modal is scoped to the equipment's cluster and to +drivers on an **Equipment-kind** namespace, so a driver-less equipment shows +no eligible drivers until you bind one (edit the equipment and pick a driver). + +**Galaxy / AVEVA System Platform tags are not shown in this tree.** They hang +off the driver's folder path and are auto-materialised from the Galaxy +browse rather than being equipment-bound, so they stay on the **Drivers** tab +of their cluster (`/clusters/{id}/drivers`), where the address picker browses +the live Galaxy hierarchy. + +### Virtual tags + +A virtual tag is bound to an equipment and driven by a **script** (no driver). +Pick its script in the Virtual tag modal; the data type is chosen from the +standard OPC UA type list. + +## Bulk import + +**Import equipment CSV** (toolbar) bulk-creates equipment across many lines +and clusters in one pass. After an import the whole tree reloads. + +## Applying changes + +Edits here change the configuration only. As the page header notes, +**changes apply on the next deployment** — run a **Deploy** (Deployments +page) to push them into the running address space. + +## See also + +- [Configuration.md](Configuration.md) — the underlying config entities. +- [VirtualTags.md](VirtualTags.md) — the scripting/virtual-tag engine. +- Design + decision log: [plans/2026-06-08-global-uns-management-design.md](plans/2026-06-08-global-uns-management-design.md).