Avatar

Please consider registering
guest

sp_LogInOut Log In sp_Registration Register

Register | Lost password?
Advanced Search

— Forum Scope —




— Match —





— Forum Options —





Minimum search word length is 3 characters - maximum search word length is 84 characters

sp_Feed Topic RSS sp_TopicIcon
Read history
June 13, 2023
11:09, EEST
Avatar
Sabari
Member
Members
Forum Posts: 62
Member Since:
June 21, 2021
sp_UserOfflineSmall Offline

Hi,
I have a client connected to an OPC UA server. If the connection is lost between the two, does the sdk provide a mechanism to allow the client to retrieve the history of the nodes in the server (the node values during the period when the connection was lost)? If so, how should this mechanism be implemented?

Thanks

June 14, 2023
11:22, EEST
Avatar
Matti Siponen
Moderator
Members

Moderators
Forum Posts: 349
Member Since:
February 11, 2020
sp_UserOfflineSmall Offline

Hello,

Typically Subscriptions and MonitoredItems would handle connection breaks automatically. As long as the MonitoredItems have sufficiently large queue sizes, they should be able to store the Values sampled during the connection break and report them after the connection has been restored.

If the Server does not support sufficiently large queue sizes or connection breaks are so long that the Subscription times out and is deleted on the Server, you might be able to get the Values from the beginning of the connection break to its end by reading history. You can detect when the connection breaks and when it is restored with onStateChange method of ServerStatusListener, so you could use it to trigger reading history. Though, it is not guaranteed that the Server supports reading history for the monitored Nodes.

June 15, 2023
17:02, EEST
Avatar
Sabari
Member
Members
Forum Posts: 62
Member Since:
June 21, 2021
sp_UserOfflineSmall Offline

Hello,
thank for your reply.

I saw in the example code supplied with the SDK that the logging is done in a variable. What should I do or what should I change so that I can easily store the history in a database?

Thnaks

June 16, 2023
9:47, EEST
Avatar
Matti Siponen
Moderator
Members

Moderators
Forum Posts: 349
Member Since:
February 11, 2020
sp_UserOfflineSmall Offline

Hello,

Storing the history to a database is outside the scope of the SDK support. MyHistorian class of SampleConsoleServer sample application demonstrates how to store and access history in memory, so you can use it as a starting point in designing how to use a database instead of memory.

If you need an application that stores and accesses history data in a database, please, take a look at Prosys OPC UA Historian: https://www.prosysopc.com/products/opc-ua-historian/

July 5, 2023
11:33, EEST
Avatar
Sabari
Member
Members
Forum Posts: 62
Member Since:
June 21, 2021
sp_UserOfflineSmall Offline

Hi,
thank for your reply.

I also want to historicize a varibale that I load from an xml model, then save and read the values from a varibale in memory. Basically to do as in the prosys example but not create the variable in the code but rather load it via an xml model. Can you help me please ?

Thanks

July 5, 2023
13:10, EEST
Avatar
Jouni Aro
Moderator
Moderators
Forum Posts: 1026
Member Since:
December 21, 2011
sp_UserOfflineSmall Offline

If you need to find a node that was loaded from a nodeset XML, you will just need to find it with ‘UaServer.getAddressSpace().getNode(nodeId)’.

July 5, 2023
15:44, EEST
Avatar
Sabari
Member
Members
Forum Posts: 62
Member Since:
June 21, 2021
sp_UserOfflineSmall Offline

I used this instruction ‘UaServer.getAddressSpace().getNode(nodeId)’ to get the node. And then, I used ‘MyHistorian.addVariableHistory(v);’ from example code supplied with the SDK.
When I browse the OPC UA tree with an OPC UA client, I see that logging is enabled on the node but when I try to read the log values I get the message : “No history values received for node ‘NS6|Numeric|6016’ “.

The node I create with the code:

UaVariableNode historised;
….
final NodeId historisedTypeId = new NodeId(this.getNamespaceIndex(), “HistorisedType”);
UaType historisedType = this.addType(historisedTypeId, “HistorisedType”, baseDataVariableType);
final NodeId historisedId = new NodeId(this.getNamespaceIndex(), “Historised”);
UaDataType historisedDoubleType = getServer().getNodeManagerRoot().getDataType(DataTypeIdentifiers.Double);
historised = new CacheVariable(this, historisedId, “Historised”, LocalizedText.NO_LOCALE);
historised.setDataType(historisedDoubleType);
historised.setTypeDefinition(historisedType);
this.getServer().getNodeManagerRoot().getObjectsFolder().addComponent(historised);

I add the node ‘historised’ in history by using : ‘MyHistorian.addVariableHistory(historised);’

For this node ‘historised’, history is enabled and the data is saved in the varibale in memory, but for the node I get from the xml model, the values are not saved.

July 5, 2023
17:00, EEST
Avatar
Jouni Aro
Moderator
Moderators
Forum Posts: 1026
Member Since:
December 21, 2011
sp_UserOfflineSmall Offline

Are you updating the variable at runtime as well?

July 5, 2023
17:34, EEST
Avatar
Sabari
Member
Members
Forum Posts: 62
Member Since:
June 21, 2021
sp_UserOfflineSmall Offline

Yes,
Below, is my function for simulating the varibal update.

int dx = 0;

public void simulate() throws StatusException, IllegalArgumentException {
UaNode historisedNode = this.getServer().getAddressSpace()
.getNode(NodeId.parseNodeId(“ns=5;i=6016”));
final DataValue v = ((CacheVariable) histoTest).getValue();
Double nextValue1 = v.isNull() ? 0 : v.getValue().doubleValue() + dx;
if (nextValue = 50) {
dx = -1;
}
try {
((CacheVariable) historisedNode ).updateValue(nextValue1);
} catch (Exception e) {
log.error(“Error while simulating {}”, e.getMessage());
}
}

In another class, I call the method periodically

@Scheduled(fixedDelay = 2000, initialDelay = 60000)
public final synchronized void simulate() throws IllegalArgumentException, StatusException {
nodeManager.simulate();
}

July 6, 2023
10:21, EEST
Avatar
Jouni Aro
Moderator
Moderators
Forum Posts: 1026
Member Since:
December 21, 2011
sp_UserOfflineSmall Offline

You seem to be updating ‘historisedNode’ with ‘histoTest + dx’. That is a constant value, unless you also update ‘histoTest’ somewhere…

July 6, 2023
10:51, EEST
Avatar
Sabari
Member
Members
Forum Posts: 62
Member Since:
June 21, 2021
sp_UserOfflineSmall Offline

I made a mistake when I posted the code here.
It’s “UaNode histoTest = this.getServer().getAddressSpace().getNode(NodeId.parseNodeId(“ns=5;i=6016″));”
instead of “UaNode historisedNode = this.getServer().getAddressSpace().getNode(NodeId.parseNodeId(“ns=5;i=6016”));”

July 6, 2023
11:26, EEST
Avatar
Jouni Aro
Moderator
Moderators
Forum Posts: 1026
Member Since:
December 21, 2011
sp_UserOfflineSmall Offline

How about ‘dx’ – do you change it to 1 somewhere – in your example it’s 0.

But, in general, it’s not really possible to debug your code further like this. You need to log the values of your variables, check that they are updating and then debug the VariableHistory and MyHistorian. They are all part of the sample code, so not really part of the SDK. If it does not work properly, there must be some configuration wrong somewhere.

So, if you need further assistance, please contact by email and we will sort it out.

July 6, 2023
15:30, EEST
Avatar
Sabari
Member
Members
Forum Posts: 62
Member Since:
June 21, 2021
sp_UserOfflineSmall Offline

I finally found the problem, I hadn’t created my CustomNodeManager with the right namespace.
I have a question about the sample code for the prosys sdk for the server. In the MyHistorian class there is a method:

public void addVariableHistory(UaVariableNode variable) {
ValueHistory history = new ValueHistory(variable);
// History is being collected
variable.setHistorizing(true);
// History can be read
variable.setAccessLevel(
AccessLevelType.of(AccessLevelType.CurrentRead, AccessLevelType.CurrentWrite, AccessLevelType.HistoryRead));
NodeId nodeId =
new NodeId(variable.getNodeId().getNamespaceIndex(), variable.getNodeId().getValue() + “HAConfiguration”);
HistoricalDataConfigurationType historicalDataConf =
variable.getNodeManager().createInstance(HistoricalDataConfigurationType.class, “HA Configuration”, nodeId);
try {
historicalDataConf.setStepped(history.isStepped());
} catch (StatusException e) {
throw new RuntimeException(e);
}
variable.addReference(historicalDataConf, Identifiers.HasHistoricalConfiguration, false);

variableHistories.put(variable, history);
}

I don’t understant the piece of code :

NodeId nodeId =
new NodeId(variable.getNodeId().getNamespaceIndex(), variable.getNodeId().getValue() + “HAConfiguration”);
HistoricalDataConfigurationType historicalDataConf =
variable.getNodeManager().createInstance(HistoricalDataConfigurationType.class, “HA Configuration”, nodeId);
try {
historicalDataConf.setStepped(history.isStepped());
} catch (StatusException e) {
throw new RuntimeException(e);
}

It this essentiel for historisation to work ?

July 6, 2023
16:40, EEST
Avatar
Jouni Aro
Moderator
Moderators
Forum Posts: 1026
Member Since:
December 21, 2011
sp_UserOfflineSmall Offline

Very good that you figured it ou!

The ‘HA Configuration’ is optional. It is supposed to provide details about the Historical Configuration, as defined in the OPC UA specification.

Forum Timezone: Europe/Helsinki

Most Users Ever Online: 1919

Currently Online:
33 Guest(s)

Currently Browsing this Page:
1 Guest(s)

Top Posters:

Heikki Tahvanainen: 402

hbrackel: 144

rocket science: 88

pramanj: 86

Francesco Zambon: 83

Ibrahim: 78

Sabari: 62

kapsl: 57

gjevremovic: 49

Xavier: 43

Member Stats:

Guest Posters: 0

Members: 726

Moderators: 7

Admins: 1

Forum Stats:

Groups: 3

Forums: 15

Topics: 1529

Posts: 6471

Newest Members:

gabriellabachus, Deakin, KTP25Zof, Wojciech Kubala, efrennowell431, wilfredostuart, caitlynfajardo, jeromechubb7, franciscagrimwad, adult_gallery

Moderators: Jouni Aro: 1026, Pyry: 1, Petri: 0, Bjarne Boström: 1032, Jimmy Ni: 26, Matti Siponen: 349, Lusetti: 0

Administrators: admin: 1