In building an OPC UA Server, what technique should be used to update properties under the Server Object? There are properties which are probably static but are never set (such as LocalTime) and others which should be updated occasionally by the running OPC UA Server (such as ServiceLevel). I tried using WriteAttribute on the properties but this fails with a write access error. This stands to reason because the Server Object properties are in UA’s “0” namespace. I have figured out how to create and populate my own properties under VendorServerInfo but these properties are in my namespace.
I am using the .NET SDK. You’re right! I was able to look up a Node and then set its value directly. I had already tried this before posting my question but it turns out I was experimenting with a complex data type and setting its value the wrong way. I will elaborate in case others run into this problem. I should have started with simpler stuff. For example, this works:
BaseVariableState bvs = (BaseVariableState)Server.DiagnosticsNodeManager.FindPredefinedNode(VariableIds.Server_ServiceLevel, typeof(BaseVariableState));
bvs.Value = 200;
Server.ServiceLevel is a simple data type (a byte) so setting its value is straightforward. What I had attempted first was to set Server.ServerStatus.State to something other than the default (Running). I noticed that the ServerObjectState type has a ServerStatus member, so I tried:
ServerObjectState serverState = (ServerObjectState)Server.DiagnosticsNodeManager.FindPredefinedNode(ObjectIds.Server, typeof(ServerObjectState));
serverState.ServerStatus.State.Value = ServerState.Suspended;
This doesn’t work. It appears that something in the SDK overwrites this value because the client never sees the change. I then tried accessing the State member directly:
BaseVariableState bvs = (BaseVariableState)Server.DiagnosticsNodeManager.FindPredefinedNode(VariableIds.Server_ServerStatus_State, typeof(BaseVariableState));
bvs.Value = ServerState.Suspended;
This doesn’t work either. Finally, I tried accessing the Server.ServerStatus structure:
BaseVariableState bvs = (BaseVariableState)Server.DiagnosticsNodeManager.FindPredefinedNode(VariableIds.Server_ServerStatus, typeof(BaseVariableState));
ServerStatusDataType stat = bvs.Value as ServerStatusDataType;
stat.State = ServerState.Suspended;
This does work! Armed with this know-now, I tackled my other interest: Server.LocalTime. Here’s what I did:
BaseVariableState bvs= (BaseVariableState)server.DiagnosticsNodeManager.FindPredefinedNode(VariableIds.Server_LocalTime, typeof(BaseVariableState));
bvs.Value = Utils.GetTimeZoneInfo(); // returns TimeZoneDataType
This works too. Thank you for your help!
1 Guest(s)