Full OPC UA server on .NET Framework 4.8 (x86) exposing AVEVA System Platform Galaxy tags via MXAccess. Mirrors Galaxy object hierarchy as OPC UA address space, translating contained-name browse paths to tag-name runtime references. Components implemented: - Configuration: AppConfiguration with 4 sections, validator - Domain: ConnectionState, Quality, Vtq, MxDataTypeMapper, error codes - MxAccess: StaComThread, MxAccessClient (partial classes), MxProxyAdapter using strongly-typed ArchestrA.MxAccess COM interop - Galaxy Repository: SQL queries (hierarchy, attributes, change detection), ChangeDetectionService with auto-rebuild on deploy - OPC UA Server: LmxNodeManager (CustomNodeManager2), LmxOpcUaServer, OpcUaServerHost with programmatic config, SecurityPolicy None - Status Dashboard: HTTP server with HTML/JSON/health endpoints - Integration: Full 14-step startup, graceful shutdown, component wiring 175 tests (174 unit + 1 integration), all passing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
85 lines
3.1 KiB
Markdown
85 lines
3.1 KiB
Markdown
# OPC UA Server Layout — Build Plan
|
|
|
|
## Overview
|
|
|
|
Extract the Galaxy object hierarchy and tag definitions from the ZB (Galaxy Repository) database to construct an OPC UA server address space. The root node is hardcoded as **ZB**.
|
|
|
|
## Step 1: Build the Browse Tree
|
|
|
|
Run `queries/hierarchy.sql` to get all deployed automation objects and their parent-child relationships.
|
|
|
|
For each row returned:
|
|
- `parent_gobject_id = 0` → child of the root ZB node
|
|
- `is_area = 1` → create as an OPC UA folder node (organizational)
|
|
- `is_area = 0` → create as an OPC UA object node (container for tags)
|
|
- Use `browse_name` as the OPC UA BrowseName/DisplayName
|
|
- Store `gobject_id` and `tag_name` for attribute lookup and tag reference translation
|
|
|
|
Build the tree by matching each row's `parent_gobject_id` to another row's `gobject_id`. The result is:
|
|
|
|
```
|
|
ZB (root, hardcoded)
|
|
└── DEV (folder, is_area=1)
|
|
├── DevAppEngine (object)
|
|
├── DevPlatform (object)
|
|
└── TestArea (folder, is_area=1)
|
|
├── DevTestObject (object)
|
|
└── TestMachine_001 (object)
|
|
├── DelmiaReceiver (object, browse_name from contained_name)
|
|
└── MESReceiver (object, browse_name from contained_name)
|
|
```
|
|
|
|
## Step 2: Attach Attributes as Tag Nodes
|
|
|
|
Run `queries/attributes.sql` to get all user-defined attributes for deployed objects.
|
|
|
|
For each attribute row:
|
|
- Match to the browse tree via `gobject_id`
|
|
- Create an OPC UA variable node under the matching object node
|
|
- Use `attribute_name` as the BrowseName/DisplayName
|
|
- Use `full_tag_reference` as the runtime tag path for read/write operations
|
|
- Map `mx_data_type` to OPC UA built-in types:
|
|
|
|
| mx_data_type | Description | OPC UA Type |
|
|
|--------------|-------------|-------------|
|
|
| 1 | Boolean | Boolean |
|
|
| 2 | Integer | Int32 |
|
|
| 3 | Float | Float |
|
|
| 4 | Double | Double |
|
|
| 5 | String | String |
|
|
| 6 | Time | DateTime |
|
|
| 7 | ElapsedTime | Double (seconds) or Duration |
|
|
|
|
- If `is_array = 1`, create the variable as an array with rank 1 and dimension from `array_dimension`
|
|
|
|
## Step 3: Monitor for Changes
|
|
|
|
Poll `queries/change_detection.sql` on a regular interval (e.g., every 30 seconds).
|
|
|
|
```
|
|
SELECT time_of_last_deploy FROM galaxy;
|
|
```
|
|
|
|
Compare the returned `time_of_last_deploy` to the last known value:
|
|
- **No change** → do nothing
|
|
- **Changed** → a deployment occurred; re-run Steps 1 and 2 to rebuild the address space
|
|
|
|
This handles objects being deployed, undeployed, added, or removed.
|
|
|
|
## Connection Details
|
|
|
|
See `connectioninfo.md` for database connection parameters and sqlcmd usage.
|
|
|
|
```
|
|
sqlcmd -S localhost -d ZB -E -Q "YOUR QUERY HERE"
|
|
```
|
|
|
|
## Query Files
|
|
|
|
| File | Purpose |
|
|
|------|---------|
|
|
| `queries/hierarchy.sql` | Deployed object hierarchy with browse names and parent relationships |
|
|
| `queries/attributes.sql` | User-defined attributes with data types and array dimensions |
|
|
| `queries/attributes_extended.sql` | All attributes (system + user-defined) with data types and array dimensions |
|
|
| `queries/change_detection.sql` | Poll galaxy.time_of_last_deploy for deployment changes |
|