OPC UA .NET SDK:如何写入从Nodeset2 XML导入的预定义节点?
解决Nodeset2导入节点的Value属性写入问题
1. 先搞定节点的可写权限
从Nodeset2导入的节点默认大概率是只读的,你得先把它的Value属性权限改成可写。可以在NodeManager初始化或者导入完成后做这个操作:
// 找到目标节点 var node = FindNode(SystemContext, targetNodeId); if (node is BaseDataVariableNode variableNode) { // 给Value属性开可写权限 variableNode.WriteMask |= AttributeWriteMask.Value; variableNode.UserWriteMask |= AttributeWriteMask.Value; }
2. 用服务器内部的正确方法更新值
别用面向客户端的WriteAttribute,服务器自己改值有更直接的方式,还能触发值变化通知:
// 拿到要更新的节点(需转为BaseDataVariableNode) var variableNode = FindNode(SystemContext, targetNodeId) as BaseDataVariableNode; if (variableNode == null) return; // 构造带时间戳和状态的新值 var newDataValue = new DataValue(new Variant(123)) { SourceTimestamp = DateTime.UtcNow, ServerTimestamp = DateTime.UtcNow, StatusCode = StatusCodes.Good }; // 直接更新,第三个参数设为true会自动通知客户端值变了 variableNode.SetValue(SystemContext, newDataValue, true);
3. 别在Read回调里做写入操作
Read回调是处理客户端读请求的地方,你在这里写值会触发权限校验,哪怕是服务器自己也会被拦,而且逻辑上也不合理。应该在业务逻辑线程或者事件里更新值,别跟读请求绑在一起。
4. 排查节点类型问题
要确认你改的是BaseDataVariableNode类型的节点,ObjectNode这类节点本身就没有Value属性可写。如果是自定义节点,得确保它继承了支持值更新的基类。
关于SetChildValue失败的说明
SetChildValue是用来更新节点的子节点值的,不是当前节点的Value。你传自身的BrowseName肯定没用,要更新当前节点的Value就用上面的SetValue方法。
内容的提问来源于stack exchange,提问作者user24248660
相关产品推荐
相关产品推荐

