I am interacting with an Allen Bradley PLC to gather data from equipment it is controlling. The basic setup is the PLC gathers information from the process and alerts Ignition with a handshake tag. Ignition stores data in database and resets the handshake. Only five values are exchanged (three of them are strings that could be about 900 bytes long). The code below executing in a tag change scrip is my current approach. I'm looking for advice on any efficiencies or completely different approaches. The turn around on this handshake is a few seconds and it's really adding up in the process time. I've thought of splitting the db write off in a separate thread so I can get right back to the PLC. However, it seems that it's the OPC reads/writes that are dominating the time.
def valueChanged(tag, tagPath, previousValue, currentValue, initialChange, missedEvents):
# if the send tag change isn't from a restart and has just changed to true
if((initialChange != True) and (currentValue.value == True)):
# read the sent seqence number, increment it, return it and acknowledgement that we are in process
sequenceResponse = system.opc.readValue("Ignition OPC UA Server", "[Z1000_PLC]Program:Supervisor_PalletData.p_WeldReq[0].Cmd.SeqNum").value + 1
taglist_1 = ["[Z1000_PLC]Program:Supervisor_PalletData.p_WeldReq[0].Stat.Ready",
"[Z1000_PLC]Program:Supervisor_PalletData.p_WeldReq[0].Stat.Done",
"[Z1000_PLC]Program:Supervisor_PalletData.p_WeldReq[0].Stat.AckNum",
"[Z1000_PLC]Program:Supervisor_PalletData.p_WeldReq[0].Stat.AckSend",
"[Z1000_PLC]Program:Supervisor_PalletData.p_WeldReq[0].Stat.IP"]
valuelist_1 = [False,False,sequenceResponse,True,True]
system.opc.writeValues("Ignition OPC UA Server", taglist_1, valuelist_1)
# capture the job number and weld data with direct opc reads from PLC
taglist_2 = ["[Z1000_PLC]Program:Supervisor_PalletData.p_WeldData[0].JobNumber",
"[Z1000_PLC]Program:Supervisor_PalletData.p_WeldData[0].WeldSummary",
"[Z1000_PLC]Program:Supervisor_PalletData.p_WeldData[0].VoltageWF",
"[Z1000_PLC]Program:Supervisor_PalletData.p_WeldData[0].CurrentWF",
"[Z1000_PLC]Program:Supervisor_PalletData.p_WeldData[0].WeldX",
"[Z1000_PLC]Program:Supervisor_PalletData.p_WeldData[0].WeldY"]
qualifiedList = system.opc.readValues("Ignition OPC UA Server",taglist_2)
jobNumber = qualifiedList[0].getValue()
weldSummary = qualifiedList[1].getValue()
voltageWF = qualifiedList[2].getValue()
currentWF = qualifiedList[3].getValue()
weldX = qualifiedList[4].getValue()
weldY = qualifiedList[5].getValue()
# insert values into the weld database
parameters = {"welderID":40,"jobNumber":str(jobNumber),"weldSummary":str(weldSummary),"voltageWF":str(voltageWF),"currentWF":str(currentWF),"weldX":float(weldX),"weldY":float(weldY)}
system.db.runNamedQuery("SPM_LineControl","Insert_Weld_Raw",parameters)
# signal that we are no longer in process, done and ready for next weld
taglist_3 = ["[Z1000_PLC]Program:Supervisor_PalletData.p_WeldReq[0].Stat.IP",
"[Z1000_PLC]Program:Supervisor_PalletData.p_WeldReq[0].Stat.Done",
"[Z1000_PLC]Program:Supervisor_PalletData.p_WeldReq[0].Stat.AckSend",
"[Z1000_PLC]Program:Supervisor_PalletData.p_WeldReq[0].Stat.Ready"]
valuelist_3 = [False,True,False,True]
system.opc.writeValues("Ignition OPC UA Server", taglist_3, valuelist_3)