Tag Event Scripts on Value Changed slow execution time

Im using tag event scripting for communication between PLC and Manufacturing Execution System which is using Oracle DataBase. The sctript is realy simple, yet it takes about 400ms to execute.

Script starts when Tag WriteRequest gets value 1 from PLC.

wert = system.tag.readBlocking(["[default]St70/Pm701/ST70_PM701_PRODUCTPACKING.value"])[0].value #Telegram ready to be sent to the MES
prod = system.tag.readBlocking(["[default]St70/Pm701/PisanieDoBazyProdukcyjnej.value"])[0].value #Sending signals to the production DB
test = system.tag.readBlocking(["[default]St70/Pm701/PisanieDoBazyTestowej.value"])[0].value #Sending signals to the test DB
testConnection = system.tag.readBlocking(["[default]AvailabilityDBTest.value"])[0].value #Connection with test DB
prodConnection = system.tag.readBlocking(["[default]AvailabilityDBProd.value"])[0].value #Connection with production DB
	
if currentValue.value == 1: #Signal for sending a telegram to the database
	if test == 1 and testConnection == 1: #Are we writing to the test base and is there a connection to the test base
		system.db.runUpdateQuery("INSERT INTO QMES_QOPC_IMPORT (NAME, DATUMZEIT, ZEIT_MS, WERT, STATUS) VALUES ('ST70_PM701_PRODUCTPACKING', SYSDATE, 0, '%s', 0)" %(wert),"DB_TEST") #Sending a telegram to the test base
		system.tag.writeBlocking(["[default]St70/Pm701/WriteDone"],[1]) #Send a signal WriteDone
	if prod == 1 and prodConnection == 1: #Are we writing to the production base and is there a connection to the production base
		system.db.runUpdateQuery("INSERT INTO QMES_QOPC_IMPORT (NAME, DATUMZEIT, ZEIT_MS, WERT, STATUS) VALUES ('ST70_PM701_PRODUCTPACKING', SYSDATE, 0, '%s', 0)" %(wert),"DB_TEST") #Send a telegram to the database
		system.tag.writeBlocking(["[default]St70/Pm701/WriteDone"],[1]) #Send a signal WriteDone
		
if currentValue.value == 0: #Reset of WriteRequest by PLC
	system.tag.writeBlocking(["[default]St70/Pm701/WriteDone"],[0]) #Reset WriteDone

We measured the time by enableing History on both tags.
image

In previous projects made in Zenon, similar operations took less than 50ms. Is there any way to improve the time of script execution?

You can try combining your tag read and write operations. I also suggest using a logger to measure the script execution. You can also add more points using nanoTime() to see which portion of the script is taking longer.

from java.lang.System import nanoTime().

start = nanoTime()

logger = system.util.getLogger('myLogger')

tagListIn = [
	         "[default]St70/Pm701/ST70_PM701_PRODUCTPACKING.value",
			 "[default]St70/Pm701/PisanieDoBazyProdukcyjnej.value",
			 "[default]St70/Pm701/PisanieDoBazyTestowej.value",
			 "[default]AvailabilityDBTest.value",
			 "[default]AvailabilityDBProd.value"
			]

tagListOut = ["[default]St70/Pm701/WriteDone"]

query = "INSERT INTO QMES_QOPC_IMPORT (NAME, DATUMZEIT, ZEIT_MS, WERT, STATUS) VALUES ('ST70_PM701_PRODUCTPACKING', SYSDATE, 0, '%s', 0)"

trigger = currentValue.value
writeDoneValue = 0

if trigger:
	wert, prod, test, testConnection, prodConnection = [tag.value for tag in system.tag.readBlocking(tagListIn)]	

	if test and testConnection:
		system.db.runUpdateQuery(query % (wert), 'DB_TEST')
		writeDoneValue = 1

	if prod and prodConnection:
		system.db.runUpdateQuery(query % (wert), 'DB_PROD')
		writeDoneValue = 1

system.tag.writeBlocking(["[default]St70/Pm701/WriteDone"],[writeDoneValue])		

end = nanoTime()

logger.info('Execution time was {} ms'.format((end - start)/10000000.0)) #Execution time in ms.
1 Like

Thank you very much, execution time has decreased to 15-16ms.
I had to remove part of the script used to measure execution time, to run the script. Do i need to install additional libraries to use it?

Oops. The import line shouldn’t have parenthesis.

from java.lang.System import nanoTime

I’d suggest one change: instead of assigning 1 to writeDoneValue, use the return of the query (which should be the number of affected rows), and maybe replace runUpdateQuery with runPrepUpdate.

Also, but that’s… a personal thing, I’d rather avoid using just if test if I’m looking specifically for test == 1, but there’s not enough context to know what values those variables can take. If they can only be 0 or 1, then I’d suggest making them explicit booleans.

There’s enough context to assume boolean with the picture at the top of his post. It’s easy to miss, as I had to look closer for it. :wink:

I generally use flags like writeDoneValue, because it’s explicit, and, while I didn’t put any real comments in this snippet, I try to write my code as if the guy maintaining it after me is a serial killer who knows where I live.

3 Likes

This is a good policy. Especially if the person reading it 6 months from now who wants to kill the original author is yourself :upside_down_face:

3 Likes

I'm not suggesting to get rid of the flag, but to assign it the return of the query instead of a constant. So that you know the write was succesful. And maybe cast it to a boolean.