Data loss when trying to connect to ProSys Simulation Server #440
Replies: 3 comments 19 replies
-
i hope you read the opc ua reference part befor send stuff directly there is a publishing interval which only sends queued notifications each x sec. |
Beta Was this translation helpful? Give feedback.
-
here is the python-opcua example i used for the screenshot this sample server has a trigger wich will be set by the client an then the server start sampling after the subscription is already made by client and then it runs for a defined time and then you can compare the output (chose an array because you can see the pattern an if there is a missing message you will see it fast) client.py from opcua import Client
from opcua import ua
class SubHandler(object):
"""
Subscription Handler. To receive events from server for a subscription
data_change and event methods are called directly from receiving thread.
Do not do expensive, slow or network operation there. Create another
thread if you need to do such a thing
"""
def datachange_notification(self, node, val, data):
print(val)
if __name__ == "__main__":
client = Client("opc.tcp://localhost:4840")
client.connect()
client.load_type_definitions()
handler = SubHandler()
sub = client.create_subscription(50, handler)
handle = sub.subscribe_data_change(client.get_node("ns=2;i=1"),queuesize=1000)
trigger = client.get_node("ns=2;i=2")
trigger.set_value(True) server.py import time, copy, datetime
from opcua import Server, ua
myarray = []
for item in range(64):
myarray.append(0)
if __name__ == "__main__":
server = Server()
server.set_endpoint("opc.tcp://127.0.0.1:4840/")
idx = server.register_namespace("test")
var = server.get_objects_node().add_variable(idx, "MyArray", ua.Variant(value=myarray, varianttype=ua.VariantType.Int64))
trigger = server.get_objects_node().add_variable(idx, "Trigger", ua.Variant(value=False, varianttype=ua.VariantType.Boolean))
trigger.set_writable(True)
server.start()
start = time.time()
while 1:
if trigger.get_value() == True:
for idx, item in enumerate(myarray):
time.sleep(0.005)
myarray[idx]+=1
val = copy.copy(myarray)
dv = ua.DataValue(ua.Variant(value=val, varianttype=ua.VariantType.Int64))
var.set_value(dv)
print(var.get_value())
if (time.time() - start) >= 10:
break
else:
time.sleep(0.050)
time.sleep(60)
server.stop() |
Beta Was this translation helpful? Give feedback.
-
@KishanKishore Just for fun, what happens if you run your test with 10 subscriptions, each with 10 nodes? |
Beta Was this translation helpful? Give feedback.
-
I am using the sync wrapper present in the
opcua-asynio
library in combination with themultiprocessing
module to connect to a ProSys Simulation Server. I have around 4000 nodes configured in the server.I have a global in memory
Queue (from the multiprocessing package)
to which the data is being pushed after it is received in thedatachange_notification
method.I am trying to keep the execution time of the
datachange_notification
callback as short as possible because it has been mentioned in several places that doing time taking operations within this callback can cause problems.Here is my Subscription Handler class.
This is my target method which is running in a separate process and subscribes to a given set of nodes:
I ran this for exactly 1 minute with 100 nodes and then later counted the total number of values received per node (in the main process):
The expected number of points is 120 with a publishing interval of 500 ms (The Simulation Server is also publishing at the same interval). But I receive only 17-18 values for every node.
If I reduce the number of nodes to 10 or lesser then the number of data points received are around 120. Is there a problem in using this library with
multiprocessing
or am I doing something incorrectly ? Any suggestions are appreciated. I need to be supporting 4000 nodes per process. What would be the best design for thedatachange_notofication
callback to handle a large number of nodes in a subscription?I have also noticed that currently the code here:
opcua-asyncio/asyncua/common/subscription.py
Line 115 in ee844ed
MonitoredItems
object. I am going to try to remove the loop and send theMonitoredItems
directly to reduce the number of times the callback is called. Would that be a logical thing to try ?Beta Was this translation helpful? Give feedback.
All reactions