Previously alarms were only reported to the immediate parent node and the Server node. Now ReportEventUpNotifierChain walks the full parent chain so clients subscribed at TestArea see alarms from TestMachine_001, and EventNotifier is set on all ancestors of alarm-containing nodes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5.3 KiB
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.jsonwas 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:
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 asLmxOpcUa.read ns=1;s=MESReceiver_001.MoveInPartNumbers: succeeded with good status0x00000000.read ns=1;s=MESReceiver_001.MoveInPartNumbers[]: failed withBadNodeIdUnknown(0x80340000).
Instance 2 (Redundant Secondary)
Deployed: 2026-03-28
Deployment path: C:\publish\lmxopcua\instance2
Configuration:
OpcUa.Port:4841OpcUa.ServerName:LmxOpcUa2OpcUa.ApplicationUri:urn:localhost:LmxOpcUa:instance2Dashboard.Port:8082MxAccess.ClientName:LmxOpcUa2Redundancy.Enabled:trueRedundancy.Mode:WarmRedundancy.Role:SecondaryRedundancy.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:instance1Redundancy.Enabled:trueRedundancy.Mode:WarmRedundancy.Role:PrimaryRedundancy.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).
LDAP Authentication Update
Updated: 2026-03-28
Both instances updated to use LDAP authentication via GLAuth.
Configuration changes (both instances):
Authentication.AllowAnonymous:true(anonymous can browse/read)Authentication.AnonymousCanWrite:false(anonymous writes blocked)Authentication.Ldap.Enabled:trueAuthentication.Ldap.Host:localhostAuthentication.Ldap.Port:3893Authentication.Ldap.BaseDN:dc=lmxopcua,dc=local
LDAP server: GLAuth v2.4.0 at C:\publish\glauth\ (Windows service: GLAuth)
Permission verification (instance1, port 4840):
anonymous read → allowed
anonymous write → denied (BadUserAccessDenied)
readonly read → allowed
readonly write → denied (BadUserAccessDenied)
readwrite write → allowed
admin write → allowed
alarmack write → denied (BadUserAccessDenied)
bad password → denied (connection rejected)
Alarm Notifier Chain Update
Updated: 2026-03-28
Both instances updated with alarm event propagation up the notifier chain.
Code changes:
- Alarm events now walk up the parent chain (
ReportEventUpNotifierChain), reporting to every ancestor node EventNotifier = SubscribeToEventsis set on all ancestors of alarm-containing nodes (EnableEventNotifierUpChain)- Removed separate
Server.ReportEventcall (no longer needed — the walk reaches the root)
No configuration changes required — alarm tracking was already enabled (AlarmTrackingEnabled: true).
Verification (instance1, port 4840):
alarms --node TestArea --refresh:
TestMachine_001.TestAlarm001 → visible (Severity=500, Retain=True)
TestMachine_001.TestAlarm002 → visible (Severity=500, Retain=True)
TestMachine_001.TestAlarm003 → visible (Severity=500, Retain=True)
TestMachine_002.TestAlarm001 → visible (Severity=500, Retain=True)
TestMachine_002.TestAlarm003 → visible (Severity=500, Retain=True)
alarms --node DEV --refresh:
Same 5 alarms visible at DEV (grandparent) level
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.