【问题标题】:Milo OPC UA Server with Historical Data Access具有历史数据访问功能的 Milo OPC UA 服务器
【发布时间】:2018-03-30 09:27:43
【问题描述】:

喂,

我是 milo(和 OPC-UA)的新手,并尝试使用历史数据访问实现 OPC-UA 服务器。我重用了当前的 milo 服务器示例并创建了一个历史节点。在此节点上,我可以(使用 Prosys OPC UA 客户端)查询空历史记录。我知道我必须自己实现历史节点的持久性。 到目前为止一切顺利——但我找不到任何有关处理历史读取请求以及如何返回响应的信息。更准确地说,如何将 HistoryData 添加到 HistoryReadResult

@Override
public void historyRead(HistoryReadContext context, HistoryReadDetails readDetails, TimestampsToReturn timestamps,
        List<HistoryReadValueId> readValueIds)
{
     List<HistoryReadResult> results = Lists.newArrayListWithCapacity(readValueIds.size());
     for (HistoryReadValueId readValueId : readValueIds){
         //return 3 historical entries
         DataValue v1 = new DataValue(new Variant(new Double(1)), StatusCode.GOOD, new DateTime(Date.from(Instant.now().minus(1, ChronoUnit.MINUTES))));
         DataValue v2 = new DataValue(new Variant(new Double(2)), StatusCode.GOOD, new DateTime(Date.from(Instant.now().minus(2, ChronoUnit.MINUTES))));
         DataValue v3 = new DataValue(new Variant(new Double(3)), StatusCode.GOOD,  new DateTime(Date.from(Instant.now().minus(3, ChronoUnit.MINUTES))));
         HistoryData data = new HistoryData(new DataValue[] {v1,v2,v3});
         //???
         HistoryReadResult result = new HistoryReadResult(StatusCode.GOOD, ByteString.NULL_VALUE, ??? );
         results.add(result);
     }
     context.complete(results);
}

【问题讨论】:

    标签: java opc-ua milo


    【解决方案1】:

    您需要访问规范才能成功实施历史访问服务。第 4 部分和第 11 部分。

    HistoryReadResult 构造函数中的最后一个参数应该是HistoryData 结构。 ExtensionObject 基本上是结构被编码和传输的容器。

    要创建ExtensionObject,您首先要创建一个HistoryData(或HistoryModifiedData,取决于...参见规范),然后执行ExtensionObject.encode(historyData) 之类的操作来获取完成构建@ 所需的对象987654328@.

    【讨论】:

      【解决方案2】:

      覆盖 historyRead 是正确的做法。

      HistoryReadResult result = new HistoryReadResult(StatusCode.GOOD, ByteString.NULL_VALUE,ExtensionObject.encode(data) );
      

      但是,在使用特定的 AccessLevel 和 Historizing 模式定义我的 variableNode 之前,UA-Expert 等通用客户端并未调用该方法:

              Set<AccessLevel> acclevels = new LinkedHashSet<>();
              acclevels.add(AccessLevel.CurrentRead);
              acclevels.add(AccessLevel.CurrentWrite);
              acclevels.add(AccessLevel.HistoryRead);
      
              UaVariableNode node = new UaVariableNode.UaVariableNodeBuilder(server.getNodeMap())
                      .setNodeId(new NodeId(namespaceIndex, "HelloWorld/Test/" + name))
                      .setAccessLevel(ubyte(AccessLevel.getMask(acclevels)))                  
                      .setUserAccessLevel(ubyte(AccessLevel.getMask(acclevels)))
                      .setBrowseName(new QualifiedName(namespaceIndex, name))
                      .setDisplayName(LocalizedText.english(name))
                      .setDataType(typeId)
                      .setTypeDefinition(Identifiers.BaseDataVariableType)
                      .setHistorizing(true)
                      .build();
      

      【讨论】:

        猜你喜欢
        • 2018-05-13
        • 1970-01-01
        • 1970-01-01
        • 2017-12-13
        • 1970-01-01
        • 2017-03-06
        • 1970-01-01
        • 2017-04-29
        • 1970-01-01
        相关资源
        最近更新 更多