使用C# Opc.Ua.Fx客户端读取OPC UA布尔数组节点属性值问题
问题根因
OpcValue是Opc.Ua.Fx封装的通用值包装类,实际的节点负载数据存储在它的Value属性中,你之前直接对OpcValue实例取类型、打印,只会拿到包装类的信息,或者Value属性的类型名,无法直接访问数组元素。
解决方案代码
将你代码中读取节点后的逻辑替换为以下内容即可:
// 尝试确定读取数组元素所需的数据类型 OpcValue discreteInputs = robot.hmiClient.ReadNode(1,302,OpcAttribute.Value); // 先校验读取状态,再做安全类型转换 if (discreteInputs.StatusCode == OpcStatusCode.Good) { // 提取实际值,转换为布尔数组 if (discreteInputs.Value is bool[] coilArray) { Console.WriteLine($"成功读取布尔数组,长度:{coilArray.Length}"); // 遍历访问所有元素 for (int i = 0; i < coilArray.Length; i++) { Console.WriteLine($"索引{i}值:{coilArray[i]}"); } } // 兼容部分服务器返回object数组的情况 else if (discreteInputs.Value is object[] objArray) { bool[] coilArray = objArray.Cast<bool>().ToArray(); Console.WriteLine($"成功读取转换布尔数组,长度:{coilArray.Length}"); for (int i = 0; i < coilArray.Length; i++) { Console.WriteLine($"索引{i}值:{coilArray[i]}"); } } else { Console.WriteLine($"返回值类型不匹配,实际类型为:{discreteInputs.Value?.GetType().FullName ?? "空值"}"); } } else { Console.WriteLine($"节点读取失败,状态码:{discreteInputs.StatusCode}"); } Console.Read();
可选优化:读取单个指定索引的数组元素
如果不需要读取整个数组,只需要获取指定位置的元素,可以直接用带索引参数的ReadNode重载,降低传输开销:
// 读取索引为3的数组元素,索引从0开始计数 OpcValue singleCoil = robot.hmiClient.ReadNode(new NodeId(1, 302), OpcAttribute.Value, new uint[] { 3 }); if (singleCoil.StatusCode == OpcStatusCode.Good && singleCoil.Value is bool coilValue) { Console.WriteLine($"索引3的线圈值:{coilValue}"); }
验证前置检查
可以先通过你之前获取的coilNodeAttributes确认节点属性,符合以下条件说明节点确实是一维布尔数组:
- ValueRank属性值为1
- DataType属性为Boolean类型
内容的提问来源于stack exchange,提问作者Mitchtown98
相关产品推荐
相关产品推荐

