Milo OPC UA Server with Historical Data Access

ⅰ亾dé卋堺 提交于 2020-01-03 04:19:04

问题


Hy,

I’m new to milo (and OPC-UA) and try to implement an OPC-UA server with Historical Data Access. I reused the current milo server example and create a history node. On this node I can query (with the Prosys OPC UA Client) the empty history. I know that I have to implement the persistency of the history nodes by myself. So far so good – but I could not found any information about to handle the history read request and how to return the response. More precisely how to add the HistoryData to an 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);
}

回答1:


You're going to need access to the spec to successfully implement historical access services. Part 4 and Part 11.

The last parameter in the HistoryReadResult constructor is supposed to be a HistoryData structure. ExtensionObject is basically the container that structures are encoded and transferred in.

To create that ExtensionObject you would first create a HistoryData (or HistoryModifiedData, depends... see the spec) and then do something like ExtensionObject.encode(historyData) to get the object you need to finish building the HistoryReadResult.




回答2:


Overrides historyRead is the correct way to do.

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

However method was not called by generic client such as UA-Expert before defining my variableNode with specific AccessLevel and Historizing mode like this :

        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();


来源:https://stackoverflow.com/questions/46811305/milo-opc-ua-server-with-historical-data-access

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!