How the whole procedure looks? We collect data to a string tag, which is an expression tag. It is event driven, so every time one of the variables changes, the whole expression tag updates. After that, writerequest signal tells us, to send the data to the database. As you can see, the writerequest signal arrives with some data, so the question is, isn't it too fast and that could be causing the error? On the other hand, 99% of case, expression tags updates in time.
Ideas that come to my mind right now:
Delay the script that sends data to DB. After we receive writerequest, we can wait some time, so the expression tag will have time to update?
Change the expression tag execution from event driven to fixed rate?
Ask the PLC programmer, if he can send writerequest a little bit late? The problem is, he is from another company they are very restrictive when it comes to signal processing times and will probably not agree to such a solution.
Change the polling rate of collected data to 500 ms and the writerequest to 1000 ms? But will it speed up the expression tag?
Consider using a gateway tag event script to monitor the writerequest tag, then use system.opc.readValues() to read of the rest of your values. This will avoid the race condition you're seeing.
tagPaths = ["[.]SerialNumber","[.]xOK","[.]xNOKProcess","[.]xNOKProduct","[.]Height","[.]HeightMin","[.]HeightMax"]
values = [val.value for val in system.tag.readBlocking(tagPaths)]
finalStr = ""
xSum = 0
for i,val in enumerate(values):
if i == 0:
finalString = val + "|"
elif i < 4:
xSum += int(val)
elif i == 4:
finalString += str(xSum) + "|" + val.replace(".",",") "|"
else:
finalString += val.replace(".",",") + "|"
system.tag.writeAsync(["[.]pathToWrite"],[finalString])
Maybe not the cleanest way to do it, kind of has a magic number feel to it. The index numbers in the loop are dependent on how you build the tag paths list, there are issues, but this should show you the basics that you would need to accomplish what the expression is doing. You could build the string in a single concatenation operation if desired. I also assumed that all of your tag values are strings since you were doing the integer conversion. If they are not all strings then the conversions may be un-needed.
Note that if you use a gateway tag event script (recommended) then the relative tag paths wont work and you will need to use the full path.
Maybe I misread, but I thought you might have been running INSERT queries from a tag change script, in which case running them via the S+F system would be quicker, I believe
I've started moving the code from expression tags to scripts. Do you have any idea, how to delay the start of the script for 50 ms? The writeRequest tag comes to Ignition in the same moment as one of the data tags and we need to delay the script, so all data is packed. I've tried using timer from threading library, but the script doesn't launch.
No, you just don't get the pace you request. If you use a native IA driver, the driver diagnostics will show what pace you are really getting. When there's no free time in the scan, then writes can be delayed significantly more than normal.
When using an external OPC server, you would have to look at its own diagnostics to determine your overload level, if any.