9:55, EEST
March 20, 2019
Hello ,
I use MonitoredDataItemListener for notifications data change in Node, how to after detect data change fast writen new data to node ?
The server data is changed every 200ms, to 200ms, I need a write new data for Node.
public void onDataChange(MonitoredDataItem sender, DataValue prevValue, DataValue value) {
Thread thread = new Thread() {
public void run() {
System.out.println("Thread Running");
String data = (client.getDataValue(sender.getNodeId(), sender.getAttributeId(), value));
logger.info(data);
System.out.println(data);
try {
client.writeValue(String nodeID, String value);
client.writeValue(String nodeID, String value);
logger.info("OK " + data + "HL, NV -> 10 ; 3");
} catch (ServiceException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
thread.start();
}
13:33, EEST
April 3, 2012
20:48, EEST
March 20, 2019
I need to monitoring the space where are 200 Node structures to change values. The value would be changed every 200 ms. After that change I need to record data of databases as soon as possible to Node. Could you please tell me how can I make 200 MonitoredDataItemListener for listening of changes and writing values if the change come in?
11:02, EEST
April 3, 2012
Make 200 MonitoredDataItems, add MonitoredDataItemListener to them and then add items to a Subscription. Look at the tutorials and the sample programs.
I do not understand “After that change I need to record data of databases as soon as possible to Node.”. Do you want to write them to a database OR to a server node?? The latter doesn’t make much sense, I would need to know more about your use case. But basically use UaClient.writeValue. Storing data to a database is outside of the scope of the support.
20:06, EEST
March 20, 2019
I have 200 nodes I need to watch. If a change occurs in any node – the node assigns me the ID I am looking for in the database and writes it to another node. I have to write as quickly as possible. I’m getting a response time of up to 50 ms, but sometimes I’m not notified of a change in the node.
My question is how can I make 200 listeners?
Problem explanation:
I have 200 positions, every 200ms is triggered by a change in some node – ID is written to the node to change ID I need to be alerted, after notification of changing this ID I look in the SQL database – (REST API) found data written to node in response.
12:08, EEST
April 3, 2012
For example something like this should work.
Subscription subscription = new Subscription();
List<NodeId> nodesToWatch = … (list having the NodeIds for your 200 nodes)
for (NodeId id : nodesToWatch) {
MonitoredDataItem monitoredItem = new MonitoredDataItem(id);
monitoredItem.setDataChangeListener(new MonitoredDataItemListener() {
@Override
public void onDataChange(MonitoredDataItem sender, DataValue prevValue, DataValue value) {
// Do something with the value
}
});
subscription.addItem(monitoredItem);
}
client.addSubscription(subscription);
Note that by default you wont receive datachanges if the value would be the same and only the timestamp would change. In order to receive those as well you must set the DataChangeFilter to have DataChangeTrigger.StatusValueTimestamp, i.e.
UnsignedInteger.getFromBits(DeadbandType.None.getValue()), null));
Additionally to receive faster replies you most likely want to change the Subscription settings in the constructor to have shorter publishInterval, see the javadocs for more information.
Also note that since all the value notifications to that onDataChange method happen in the same Thread (PublishTask Thread of the UaClient), you might want to handle writing, database querys etc in a different Thread.
12:30, EEST
March 20, 2019
Dear, thank you for your help in this matter. Using the filter is working good, I’m taking all values from server. Now, I find out other complication. When I write the values to server, the responses time are moving about 10 ms , 20 ms, 30 ms , 40 ms, 50 ms and again from 10 ms to 50 ms … and again 10 ms, 20 ms…. etc … I would like some enlightenment about what can make this. How to achieve the same response time or remove the increase in response time Would you please help me with?
I use the same method for answer.
14:25, EEST
April 3, 2012
Hi,
OPC UA nor normal Java JVM is not a real-time system (or the operating system you most likely are running your application with), there will be always fluctuations.
But generally speaking, check the publishinterval of the Subscription vs. the speed you are writing. Additionally if you do any blocking operations in the onDataChange method, it can delay the rest.
For more information about how the MonitoredItems and Subscriptions work, please see the specification 1.04 Part 4 sections 5.12 MonitoredItem Service Set and 5.13 Subscription Service Set
If that doesn’t help please use e.g. wireshark to see how the actual requests etc. are going + timings (https://www.prosysopc.com/blog/opc-ua-wireshark/)
15:45, EEST
March 20, 2019
Thank you for your advice. Would you please help me with other thing. Is it possible to subscription the entire structure instead of the value? Is it also necessary to set the OPC server?
When I try to put the NodeID Structure, it’s ending with error. If I put the value like NodeID, everything works well.
9:31, EEST
April 3, 2012
Please clarify what you are exactly doing and what error you are getting for “When I try to put the NodeID Structure, it’s ending with error”, there is so many ways I could interpret that in the context of OPC UA so it is really hard to say, i.e. show code for what you have done and stacktraces for errors (or UA StatusCodes in some cases, which usually say Bad_something)
I do not understand what you mean by “Is it also necessary to set the OPC server?”
If you have a node, which has a Structure Value (i.e. the DataType of the node is a subtype of the “Structure” DataType), you will get a structures from it. However it should be noted that Structures have their own encoding rules. If it is not a Structure the SDK knows, i.e. a Structure codegenerated with the codegen, SDK will try to resolve the so called “TypeDictionaries” of the server (and this needs the server to provide correct data) and gives the value as a java class DynamicStructure. You can access the fields via the methods defined in the ‘Structure’ interface.
P.S. I’m assuming you are using SDK version 4.x (currently the newest is 4.0.2), previous 3.x versions do not automatically decode unknown Structures (you will get ExtensionObjects instead, which is the encoded “wrapper” defined in the UA Binary encodings in the Part 6 of the specification).
16:01, EEST
March 20, 2019
Now, I have Barcode set in MonitoredDataItemListener. I can’t take 1_Data struggle with UA Expert – Statuscode – BadNotSupported
It would ideally be to remove the entire structure and then convert it to a Java object, then add the data to that object and write it to the OPC. But the problem of data types.
The project is there are 200 scanners (nodes) that read barcode and opc client write data to structure.
PLC read Barcode -> datachanges -> Java OPC client read Barcode value and search value in SQL DB -> Java OPC client write value to Position , X, Y, Z and Name -> after 200ms PLC set all variabiles to NULL -> Java OPC read null, null call Full REST WS.
–> 1_Data (Data type structure)
|— > Barcode (Data type Byte Array)
|— > Position (Data type Byte)
|— > X (Data type Byte)
|— >Y (Data type Byte)
|— >Z (Data type Byte)
|— > Name (Data type Byte Array)
–> 2_Data (Data type structure)
.
.
.
.
.
.
. -> 199_data structures
. -> 200_data structures
17:15, EEST
April 3, 2012
Ok, that explains a lot, thanks. This might be outside the scope of the technical support we give, as it is more about design. But I’ll try..
0. Generally the design seems a bit odd..
1. Is the PLC program/server something you have influence over i.e. can you change it?
2. I assume the DataType of 1_Data is not literally the “Structure” NodeId, i.e. “i=22”, it should refer to some node below DataTypes/Structure node.
3. Is the Value of 1_Data node really a Structure containing all the Barcode, Position, X, Y, Z, Name fields?
4. Note that UA DataType Byte does not have a Null encoding, you will get 0 instead.
5. You can write multiple values at once via UaClient.writeValues(NodeId[] nodeIds, Object[] value) method, and you’ll probably have to do it like that unless you change the PLC side (assuming the PLC will understand that single call such as to keep it in sync, otherwise you’ll get first X as 0 with Y being what it was, then X 0 and Y 0 etc.). I would recommend maybe making an UA Method instead. That way you can skip the PLC setting all to Null part and directly call REST when the Method call returns or something. Just a suggestion.
6. I recommend making some sort of “task” system etc, anything that does not directly call the DB in the same Thread as the onDataChange is called by the SDK. They are all called in the same PublishTask thread of the UaClient, blocking it via the DB call will block handling of all other datachanges.
Most Users Ever Online: 1919
Currently Online:
27 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: 729
Moderators: 7
Admins: 1
Forum Stats:
Groups: 3
Forums: 15
Topics: 1529
Posts: 6471
Newest Members:
Marypof5711, roycedelargie91, kourtneyquisenbe, ellis87832073466, zkxwilliemae, gabriellabachus, Deakin, KTP25Zof, Wojciech Kubala, efrennowell431Moderators: Jouni Aro: 1026, Pyry: 1, Petri: 0, Bjarne Boström: 1032, Jimmy Ni: 26, Matti Siponen: 349, Lusetti: 0
Administrators: admin: 1