Scripts involving OPC tags slow

Initially I thought this had something to do with a specific template I had, however after playing around in the client some more I’ve pinpointed that it has something to do with some lag involving OPC communications. We’re using the OPC-UA server to connect to roughly 7000 tags however any buttons that have a script involving read/writing to OPC tags exhibit some lag. Sometimes the script executes as expected, but other times there might be a noticeable lag (marching ants around button etc) or the script doesn’t execute the OPC writes and in some rare occasions a tag write time out woulud occur.

Are there any optimizations to try and make the communication between the clients and OPC server faster and more reliable?

Thanks.

Are you using Ignition’s own OPC-UA server directly or something else like Kepware?

Ignition’s own OPC-UA server using the Logix driver.

Instead of running a script to update the values on a button press, you could try using bidirectional bindings between the value of your components and your OPC-UA tags.

I tried using Ignition’s own built-in buttons and to write tag values using the built-in property and it also resulted in OPC write time outs.

Can you post a screenshot of your component bindings?

No scripting. I’m currently talk to support about this as well and I believe the OPC-UA Server is not communicating as reliably as it should.

1 Like

As suggested by tech support I use writeSynchronous in my mousePressed template script for my custom buttons which contain the following properties:

PB_Tag is the boolean OPC tag that the button writes to.
PB_Path is the tag path to be used with writeSynchronous.

on = 1
off = 0

if(event.source.Enabled):
	if(event.source.Toggle):
		if(event.source.PB_Tag):
			value = off
		else:
			value = on
	else:
		value = on
		
def writeToTag(tag = event.source.PB_Path, value = value):
			system.tag.writeSynchronous(tag,value)
		
system.util.invokeAsynchronous(writeToTag)

While the reliability of the button itself has improved, there are still instances where the button doesn’t do anything after being pressed and there was a brief 10-15 second window where no button presses were registered and a Write time out occurred by invokeAsynchronous. This still leads me to believe that there is a bottleneck somewhere in Ignition’s OPC-UA server as my performance specs are well within normal range.

This the error by the way and its details:

Error running function from fpmi.system.invokeAsynchronous

Traceback (most recent call last):
  File "<event:mousePressed>", line 14, in writeToTag
              at com.inductiveautomation.ignition.client.script.ClientTagUtilities$SynchronousWriteListener.waitForResponse(ClientTagUtilities.java:298)
              at com.inductiveautomation.ignition.client.script.ClientTagUtilities.writeToTagSynchronousImpl(ClientTagUtilities.java:194)
              at com.inductiveautomation.ignition.common.script.builtin.AbstractTagUtilities.writeSynchronous(AbstractTagUtilities.java:333)
              at com.inductiveautomation.ignition.common.script.builtin.AbstractTagUtilities.writeSynchronous(AbstractTagUtilities.java:321)
              at sun.reflect.GeneratedMethodAccessor562.invoke(Unknown Source)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
              at java.lang.reflect.Method.invoke(Unknown Source)

java.lang.Exception: java.lang.Exception: Write timed out [C]

              at org.python.core.Py.JavaError(Py.java:495)
              at com.inductiveautomation.ignition.client.script.ClientTagUtilities.writeToTagSynchronousImpl(ClientTagUtilities.java:198)
              at com.inductiveautomation.ignition.common.script.builtin.AbstractTagUtilities.writeSynchronous(AbstractTagUtilities.java:333)
              at com.inductiveautomation.ignition.common.script.builtin.AbstractTagUtilities.writeSynchronous(AbstractTagUtilities.java:321)
              at sun.reflect.GeneratedMethodAccessor562.invoke(Unknown Source)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
              at java.lang.reflect.Method.invoke(Unknown Source)
              at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:186)
              at com.inductiveautomation.ignition.common.script.ScriptManager$ReflectedInstanceFunction.__call__(ScriptManager.java:429)
              at org.python.core.PyObject.__call__(PyObject.java:404)
              at org.python.core.PyObject.__call__(PyObject.java:408)
              at org.python.pycode._pyx856.writeToTag$1(<event:mousePressed>:14)
              at org.python.pycode._pyx856.call_function(<event:mousePressed>)
              at org.python.core.PyTableCode.call(PyTableCode.java:165)
              at org.python.core.PyBaseCode.call(PyBaseCode.java:301)
              at org.python.core.PyFunction.function___call__(PyFunction.java:376)
              at org.python.core.PyFunction.__call__(PyFunction.java:371)
              at org.python.core.PyFunction.__call__(PyFunction.java:361)
              at org.python.core.PyFunction.__call__(PyFunction.java:356)
              at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:647)
              at com.inductiveautomation.factorypmi.application.script.builtin.ClientSystemUtilities$4.run(ClientSystemUtilities.java:403)
              at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.Exception: Write timed out [C]
              at com.inductiveautomation.ignition.client.script.ClientTagUtilities$SynchronousWriteListener.waitForResponse(ClientTagUtilities.java:298)
              at com.inductiveautomation.ignition.client.script.ClientTagUtilities.writeToTagSynchronousImpl(ClientTagUtilities.java:194)
              ... 20 more

Ignition v7.9.7 (b2018032914)
Java: Oracle Corporation 1.8.0_171

You’re going to have to show your driver load factor and diagnostic statistics for the device giving you trouble. It would be good to be displaying live statistics while you exercise the scripts that are yielding the timeouts.

The device load does spike up from the normal levels of 15-30% when idle to about 50-75% when the button presses are not responding as usual. Other than that I don’t notice anything else that could be considered unusual.

Look at your request count and your throughput for your 1-second scan class’s tags. You aren’t keeping up. The stats will only show the scheduled load, not the net load, so you must have a whole bunch of system.opc.* calls adding unaccounted load, and/or transaction groups in Opc Read mode that are triggering often enough to distort the stats. Consider splitting your 1-second tags in half, and assigning half to another driver instance to the same device.
Also, if your Logix processor is quite recent, also consider changing the CIP Connection size in the driver’s advanced settings. Instead of 500, use 4002.

1 Like

Consider also investingating/documenting how many other devices (HMIs, other branded SCADAs, RSLogix users) are also communicating with this PLC and/or through a shared PLC network interface. You might just have something else bogging down the PLC at various times, impacting your driver’s throughput. Also make sure that you have a suitable communication time slice in the PLC processor, and/or nothing but periodic tasks that leave enough CPU time for the PLC to handle messages. (Continuous tasks are eeeeevil.)

2 Likes

Thanks @pturmel. I’ll give those suggestions a shot and see how it goes.

After splitting into two device channels, the Throughput rates look more stable now than before. This is with the CIP connection size set to 4002 on both devices. Although now I see that the Mean Response Times have shot up compared to before as they’re now in the 200-300 ms range compared to under 100 ms before.

With these changes the write time out still occurs. The Communication time splice is set to 30% however it is set to Continuous tasks. After talking to the PLC programmer the next thing we will try later today is to set that time splice down to 20% but change it to Periodic tasks and see if that helps so that 20% is reserved only for communications.

Yeah, the jump in response time almost certainly means that the communications task cannot finish handling a large packet aggregate request within the time slice. Have your PLC programmer change the continuous task to as slow a periodic pace as your process will tolerate (less a modest safety factory).