Can I do inserts from a transaction group and script resets on the same tags' change event scripts?
Example:
My workorder tag transaction group triggers the transaction group to collect my infeed value.
My workorder tag change script resets my infeed value.
Or will the be a race condition?
Do I need to both insert and reset from a tag change event script?
Is a tag change event script reliable enough for inserting to tables?
I wouldn't be surprised if it gives you grief in the future.
Is it possible to set up your PLC to reset the value instead of Ignition? I'd have the PLC reset the value once it receives a good/complete status from the transaction group.
If not, do everything from a Gateway tag change event script.
If you use a gateway tag change event then yes. We run several of our transactions this way because we need to split data collected into multiple tables. It also allows for more thorough handshaking, additional data processing, and additional actions after inserting.
A basic framework from pturmel :
Gateway Tag Change Event Transaction Framework
from java.lang import Throwable
logger = system.util.getLogger("SomeProject.someScript")
cache = {}
echoTagPath = '[someProvider]path/to/trigger/echo'
failTagPath = '[someProvider]path/to/failure/bit'
opcServer = "Ignition OPC UA Server"
opcItems = [... all the opc item paths to read together ...]
transactionSQL = """Insert Into "someTable" (t_stamp, ... other columns ...)
Values (CURRENT_TIMESTAMP, ... ? placeholders for values ...)"""
def myTransaction(initialChange, newValue, event):
if initialChange:
cache['lastEcho'] = system.tag.readBlocking([echoTagPath])[0].value
# Check for zero, null, or duplicate trigger
if not newValue.value or newValue.value == cache['lastEcho']:
return
# Set the cached last trigger early to prevent accidental retriggers
# if the DB operations run long. Also prevents retriggers after failure
# unless the project is saved/restarted.
cache['lastEcho'] = newValue.value
# Obtain all of the data to record. Check for all good.
QVlist = system.opc.readValues(opcServer, opcItems)
if all([qv.quality.good for qv in QVlist]):
# extract all the values and submit the SQL
params = [qv.value for qv in QVlist]
try:
# Possibly use system.db.runSFPrepUpdate() instead.
system.db.runPrepUpdate(transactionSQL, params)
system.tag.writeBlocking([echoTagPath], [newValue.value])
except Throwable, t:
# Log and set failure handshake
logger.warn("Java Error recording transaction", t)
system.tag.writeBlocking([failTagPath], [True])
except Exception, e:
# See https://www.automation-pros.com/ignition/later.py
logger.warn("Jython Error recording transaction", later.PythonAsJavaException(e))
system.tag.writeBlocking([failTagPath], [True])
else:
# Log failed OPC reads
failed = [(item, qv) for (item, qv) in zip(opcItems, QVlist) if not qv.quality.good]
logger.warnf("OPC Read Error(s) for transaction: %s", repr(failed))
system.tag.writeBlocking([failTagPath], [True])
I like to trend the PLC value for diagnostics.
I am resetting a memory tag, positive increment counter of the PLC value.
So I would not reset from the PLC in this case.
That script seems great for letting you insert to different tables.
I am hoping that is more than I need.
I am thinking about using the tag change scripts so that I have easy access to the previous value without having to depend on an additional script and tag.
You're writing a Gateway Tag Change event script. Essentially you are writing the transaction from scratch. The event is triggered based on what tag's you assign to the event.
Throwable is a Java type, so you have to import it into Jython