Separates ApplicationUri from namespace identity so each instance in a redundant pair has a unique server URI while sharing the same Galaxy namespace. Exposes RedundancySupport, ServerUriArray, and dynamic ServiceLevel through the standard OPC UA server object. ServiceLevel is computed from role (Primary/Secondary) and runtime health (MXAccess and DB connectivity). Adds CLI redundancy command, second deployed service instance, and 31 new tests including paired-server integration. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
95 lines
3.4 KiB
Markdown
95 lines
3.4 KiB
Markdown
# Service Update Summary
|
|
|
|
Updated service instance: `C:\publish\lmxopcua\instance1`
|
|
|
|
Update time: `2026-03-25 12:54-12:55 America/New_York`
|
|
|
|
Backup created before deploy: `C:\publish\lmxopcua\backups\20260325-125444`
|
|
|
|
Configuration preserved:
|
|
- `C:\publish\lmxopcua\instance1\appsettings.json` was not overwritten.
|
|
|
|
Deployed binary:
|
|
- `C:\publish\lmxopcua\instance1\ZB.MOM.WW.LmxOpcUa.Host.exe`
|
|
- Last write time: `2026-03-25 12:53:58`
|
|
- Size: `143360`
|
|
|
|
Windows service:
|
|
- Name: `LmxOpcUa`
|
|
- Display name: `LMX OPC UA Server`
|
|
- Account: `LocalSystem`
|
|
- Status after update: `Running`
|
|
- Process ID after restart: `29236`
|
|
|
|
Restart evidence:
|
|
- Service log file: `C:\publish\lmxopcua\instance1\logs\lmxopcua-20260325_004.log`
|
|
- Last startup line: `2026-03-25 12:55:08.619 -04:00 [INF] The LmxOpcUa service was started.`
|
|
|
|
## CLI Verification
|
|
|
|
Endpoint from deployed config:
|
|
- `opc.tcp://localhost:4840/LmxOpcUa`
|
|
|
|
CLI used:
|
|
- `C:\Users\dohertj2\Desktop\lmxopcua\tools\opcuacli-dotnet\bin\Debug\net10.0\opcuacli-dotnet.exe`
|
|
|
|
Commands run:
|
|
|
|
```powershell
|
|
opcuacli-dotnet.exe connect -u opc.tcp://localhost:4840/LmxOpcUa
|
|
opcuacli-dotnet.exe read -u opc.tcp://localhost:4840/LmxOpcUa -n 'ns=1;s=MESReceiver_001.MoveInPartNumbers'
|
|
opcuacli-dotnet.exe read -u opc.tcp://localhost:4840/LmxOpcUa -n 'ns=1;s=MESReceiver_001.MoveInPartNumbers[]'
|
|
```
|
|
|
|
Observed results:
|
|
- `connect`: succeeded, server reported as `LmxOpcUa`.
|
|
- `read ns=1;s=MESReceiver_001.MoveInPartNumbers`: succeeded with good status `0x00000000`.
|
|
- `read ns=1;s=MESReceiver_001.MoveInPartNumbers[]`: failed with `BadNodeIdUnknown` (`0x80340000`).
|
|
|
|
---
|
|
|
|
## Instance 2 (Redundant Secondary)
|
|
|
|
Deployed: `2026-03-28`
|
|
|
|
Deployment path: `C:\publish\lmxopcua\instance2`
|
|
|
|
Configuration:
|
|
- `OpcUa.Port`: `4841`
|
|
- `OpcUa.ServerName`: `LmxOpcUa2`
|
|
- `OpcUa.ApplicationUri`: `urn:localhost:LmxOpcUa:instance2`
|
|
- `Dashboard.Port`: `8082`
|
|
- `MxAccess.ClientName`: `LmxOpcUa2`
|
|
- `Redundancy.Enabled`: `true`
|
|
- `Redundancy.Mode`: `Warm`
|
|
- `Redundancy.Role`: `Secondary`
|
|
- `Redundancy.ServerUris`: `["urn:localhost:LmxOpcUa:instance1", "urn:localhost:LmxOpcUa:instance2"]`
|
|
|
|
Windows service:
|
|
- Name: `LmxOpcUa2`
|
|
- Display name: `LMX OPC UA Server (Instance 2)`
|
|
- Account: `LocalSystem`
|
|
- Endpoint: `opc.tcp://localhost:4841/LmxOpcUa`
|
|
|
|
Instance 1 redundancy update (same date):
|
|
- `OpcUa.ApplicationUri`: `urn:localhost:LmxOpcUa:instance1`
|
|
- `Redundancy.Enabled`: `true`
|
|
- `Redundancy.Mode`: `Warm`
|
|
- `Redundancy.Role`: `Primary`
|
|
- `Redundancy.ServerUris`: `["urn:localhost:LmxOpcUa:instance1", "urn:localhost:LmxOpcUa:instance2"]`
|
|
|
|
CLI verification:
|
|
```
|
|
opcuacli-dotnet.exe redundancy -u opc.tcp://localhost:4840/LmxOpcUa
|
|
→ Redundancy Mode: Warm, Service Level: 200, Application URI: urn:localhost:LmxOpcUa:instance1
|
|
|
|
opcuacli-dotnet.exe redundancy -u opc.tcp://localhost:4841/LmxOpcUa
|
|
→ Redundancy Mode: Warm, Service Level: 150, Application URI: urn:localhost:LmxOpcUa:instance2
|
|
```
|
|
|
|
Both instances report the same `ServerUriArray` and expose the same Galaxy namespace (`urn:ZB:LmxOpcUa`).
|
|
|
|
## Notes
|
|
|
|
The service deployment and restart succeeded. The live CLI checks confirm the endpoint is reachable and that the array node identifier has changed to the bracketless form. The array value on the live service still prints as blank even though the status is good, so if this environment should have populated `MoveInPartNumbers`, the runtime data path still needs follow-up investigation.
|