Can you show your new script?
status = event.getCurrentValue().getValue()
if status == True:
tagPaths = ["[~]Program:MainProgram/RO/RO_1_/BATCH_DSCALE_DATE",
"[~]Program:MainProgram/RO/RO_1_/BATCH_DSCALE_TIME",
"[~]Program:MainProgram/RO/RO_1_/BATCH_DSCALE_BANO",
"[~]Program:MainProgram/RO/RO_1_/BATCH_DSCALE/BATCH_DSCALE_1_",
"[~]Program:MainProgram/RO/RO_1_/BATCH_DSCALE/BATCH_DSCALE_3_",
"[~]GA_STATUS_40_",
"[~]Program:MainProgram/RO/RO_1_/BATCH_DSCALE/BATCH_DSCALE_4_",
"[~]Program:MainProgram/RT_ROAST_AUTO_DEST",
"[~]R1_Bag_Count"]
qVals = system.tag.readBlocking(tagPaths)
date = qVals[0].value
time = qVals[1].value
job = qVals[2].value
roaster = 1
item = qVals[3].value
destcheck = qVals[5].value
greenwt = qVals[4].value
processed = 0
destcheck = qVals[5].value
roastwt = qVals[6].value
if destcheck == 1:
desttype = "Silo"
dest = qVals[7].value
params = {
'RoastDate': date,
'RoastTime': time,
'Job': job,
'Roaster': roaster,
'Item': item,
'Dest_Type': desttype,
'Dest': dest,
'Green_Wt': greenwt,
'Roast_Wt': roastwt,
'Processed': processed
}
system.db.runNamedQuery("Plant", "Insert Record to Roaster Production", params)
else:
desttype = "Bag"
dest = qVals[8].value
params = {
'RoastDate': date,
'RoastTime': time,
'Job': job,
'Roaster': roaster,
'Item': item,
'Dest_Type': desttype,
'Dest': dest,
'Green_Wt': greenwt,
'Roast_Wt': roastwt,
'Processed': processed
}
system.db.runNamedQuery("Plant", "Insert Record to Roaster Production", params)
- I started with if status = true because I only want to run this when the expression tag changes from false to true
- I dont think I changed anything from my last post but now it is not logging the data as the expression bit changes to True, now I am getting an error in like 54 saying that cannot complete insert because Date is null. As I monitor the tags in a view, I can see that the date I am grabbing the date from is not null when the script executes or when the error pops up in the logs.
- Figured out how to post formatted code
Any suggestions would be greatly appreciated.
Officially, you don't need the == True
it doesn't hurt anything, but you can just do if status
.
I would also recomend that you wrap the whole thing in an initialChange flag
if not initialChange:
#specifically use the new value that comes with the change. Note that you can also check that an actual
#value change has occured by using the previousValue object. Since a quality change
#can also trigger a tag change
status = newValue.getValue()
if status and status != previousValue.getValue():
#the rest of the script
Cleaned up in some ways, may not do exactly what you want:
if not initialChange and event.currentValue.value:
tagPaths = [
"[~]Program:MainProgram/RO/RO_1_/BATCH_DSCALE_DATE",
"[~]Program:MainProgram/RO/RO_1_/BATCH_DSCALE_TIME",
"[~]Program:MainProgram/RO/RO_1_/BATCH_DSCALE_BANO",
"[~]Program:MainProgram/RO/RO_1_/BATCH_DSCALE/BATCH_DSCALE_1_",
"[~]Program:MainProgram/RO/RO_1_/BATCH_DSCALE/BATCH_DSCALE_3_",
"[~]GA_STATUS_40_",
"[~]Program:MainProgram/RO/RO_1_/BATCH_DSCALE/BATCH_DSCALE_4_",
"[~]Program:MainProgram/RT_ROAST_AUTO_DEST",
"[~]R1_Bag_Count"
]
values = (qv.value for qv in system.tag.readBlocking(tagPaths))
date, time, job, item, greenwt, destcheck, roastwt, = values
roaster = 1
processed = 0
params = {
'RoastDate': date,
'RoastTime': time,
'Job': job,
'Roaster': roaster,
'Item': item,
'Green_Wt': greenwt,
'Roast_Wt': roastwt,
'Processed': processed
}
if destcheck == 1:
params["Dest_Type"] = "Silo"
params["Dest"] = values[7]
else:
params["Dest_Type"] = "Bag"
params["Dest"] = values[8]
system.db.runNamedQuery("Plant", "Insert Record to Roaster Production", params)
Good work more readable, it is a big plus for future improvement.
I think @PGriffith has a pretty good recommendation
What do you mean, stop the script ? Is there more code afterward that you don't want to run ?
There's no need for this when evaluating a boolean.
If bool
is true, then bool == True
returns true. Which was already bool
's value.
Same thing if it's false.
Can you show the error ?
com.inductiveautomation.ignition.common.script.JythonExecException: Traceback (most recent call last): File "", line 36, in at com.inductiveautomation.ignition.gateway.db.namedquery.NamedQueryExecutor$NamedQueryInstance.execute(NamedQueryExecutor.java:407) at com.inductiveautomation.ignition.gateway.db.namedquery.NamedQueryExecutor.execute(NamedQueryExecutor.java:173) at com.inductiveautomation.ignition.gateway.db.namedquery.GatewayNamedQueryManager.execute(GatewayNamedQueryManager.java:92) at com.inductiveautomation.ignition.gateway.script.GatewayDBUtilities.runNamedQuery(GatewayDBUtilities.java:418) at jdk.internal.reflect.GeneratedMethodAccessor449.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.base/java.lang.reflect.Method.invoke(Unknown Source) java.lang.Exception: java.lang.Exception: com.microsoft.sqlserver.jdbc.SQLServerException: Cannot insert the value NULL into column 'RoastDate', table 'RegalPLC.dbo.T20_Roaster_Production_TBL'; column does not allow nulls. INSERT fails.
at org.python.core.Py.JavaError(Py.java:547)
at org.python.core.Py.JavaError(Py.java:538)
at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:192)
at com.inductiveautomation.ignition.common.script.ScriptManager$ReflectedInstanceFunction.__call__(ScriptManager.java:549)
at org.python.core.PyObject.__call__(PyObject.java:494)
at org.python.core.PyObject.__call__(PyObject.java:498)
at org.python.pycode._pyx21380.f$0(:36)
at org.python.pycode._pyx21380.call_function()
at org.python.core.PyTableCode.call(PyTableCode.java:173)
at org.python.core.PyCode.call(PyCode.java:18)
at org.python.core.Py.runCode(Py.java:1687)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:796)
at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.runCode(ProjectScriptLifecycle.java:819)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:748)
at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.runCode(ProjectScriptLifecycle.java:800)
at com.inductiveautomation.ignition.common.script.TagChangeScriptExecutor$TagChangeExecutionCallback.execute(TagChangeScriptExecutor.java:242)
at com.inductiveautomation.ignition.common.script.TagChangeScriptExecutor$TagChangeExecutionCallback.execute(TagChangeScriptExecutor.java:194)
at com.inductiveautomation.ignition.common.util.SerialExecutionQueue$PollAndExecute.run(SerialExecutionQueue.java:102)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: org.python.core.PyException: java.lang.Exception: java.lang.Exception: com.microsoft.sqlserver.jdbc.SQLServerException: Cannot insert the value NULL into column 'RoastDate', table 'RegalPLC.dbo.T20_Roaster_Production_TBL'; column does not allow nulls. INSERT fails.
... 23 common frames omitted
Caused by: java.lang.Exception: com.microsoft.sqlserver.jdbc.SQLServerException: Cannot insert the value NULL into column 'RoastDate', table 'RegalPLC.dbo.T20_Roaster_Production_TBL'; column does not allow nulls. INSERT fails.
at com.inductiveautomation.ignition.gateway.db.namedquery.NamedQueryExecutor$NamedQueryInstance.execute(NamedQueryExecutor.java:407)
at com.inductiveautomation.ignition.gateway.db.namedquery.NamedQueryExecutor.execute(NamedQueryExecutor.java:173)
at com.inductiveautomation.ignition.gateway.db.namedquery.GatewayNamedQueryManager.execute(GatewayNamedQueryManager.java:92)
at com.inductiveautomation.ignition.gateway.script.GatewayDBUtilities.runNamedQuery(GatewayDBUtilities.java:418)
at jdk.internal.reflect.GeneratedMethodAccessor449.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:190)
... 20 common frames omitted
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Cannot insert the value NULL into column 'RoastDate', table 'RegalPLC.dbo.T20_Roaster_Production_TBL'; column does not allow nulls. INSERT fails.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:265)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1662)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:615)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:537)
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7417)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:3488)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:262)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:237)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeUpdate(SQLServerPreparedStatement.java:483)
at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:136)
at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:136)
at com.inductiveautomation.ignition.gateway.datasource.SRConnectionWrapper$SRPreparedStatement.executeUpdate(SRConnectionWrapper.java:981)
at com.inductiveautomation.ignition.gateway.datasource.SRConnectionWrapper.runPrepUpdate(SRConnectionWrapper.java:181)
at com.inductiveautomation.ignition.gateway.db.namedquery.NamedQueryExecutor$NamedQueryInstance.runPrepQuery(NamedQueryExecutor.java:507)
at com.inductiveautomation.ignition.gateway.db.namedquery.NamedQueryExecutor$NamedQueryInstance.execute(NamedQueryExecutor.java:399)
... 27 common frames omitted
if not initialChange and event.currentValue.value:
tagPaths = [
"[~]Program:MainProgram/RO/RO_1_/BATCH_DSCALE_DATE",
"[~]Program:MainProgram/RO/RO_1_/BATCH_DSCALE_TIME",
"[~]Program:MainProgram/RO/RO_1_/BATCH_DSCALE_BANO",
"[~]Program:MainProgram/RO/RO_1_/BATCH_DSCALE/BATCH_DSCALE_1_",
"[~]Program:MainProgram/RO/RO_1_/BATCH_DSCALE/BATCH_DSCALE_3_",
"[~]GA_STATUS_40_",
"[~]Program:MainProgram/RO/RO_1_/BATCH_DSCALE/BATCH_DSCALE_4_",
"[~]Program:MainProgram/RT_ROAST_AUTO_DEST",
"[~]R1_Bag_Count"
]
values = (qv.value for qv in system.tag.readBlocking(tagPaths))
date, time, job, item, greenwt, destcheck, roastwt, dest, bagnum = values
roaster = 1
processed = 0
params = {
'RoastDate': date,
'RoastTime': time,
'Job': job,
'Roaster': roaster,
'Item': item,
'Green_Wt': greenwt,
'Roast_Wt': roastwt,
'Processed': processed
}
if destcheck == 1:
params["Dest_Type"] = "Silo"
params["Dest"] = values[7]
else:
params["Dest_Type"] = "Bag"
params["Dest"] = bagnum
system.db.runNamedQuery("Plant", "Insert Record to Roaster Production", params)
Reading stacktraces is an invaluable skill anytime you're dealing with the JVM, which includes basically all of Ignition. Skip the top-fluff until you get to the innermost 'Caused By', which is often a much more clear error than the wall of text might make it seem at first.
So you gotta figure out why that date is null.
You say you're monitoring the tag, but I suggest you log the actual value you get from the tag read in the script.
The most likely cause here is a wrong tag path.
You can actually pass paths that don't exist to system.tag.readBlocking
, and it will return a perfectly valid qualified value, with value None
and quality Bad_NotFound
. I suspect that's what's going on here.
could it be that I'm referencing a relative tag path? like on the label I use to monitor the tag value I use [default]Program:MainProgram/RO/RO_1_/BATCH_DSCALE_DATE but in the script I have [~]Program:MainProgram/RO/RO_1_/BATCH_DSCALE_DATE
I'm going to mess with that and see if that helps.
After making that change, I have logged one record with no data missing... no alarms/null data errors... I think that did it!
Same script - different machine - new error:
com.inductiveautomation.ignition.common.script.JythonExecException: Traceback (most recent call last): File "", line 31, in TypeError: 'generator' object is unsubscriptable
at org.python.core.Py.TypeError(Py.java:236)
at org.python.core.PyObject.__finditem__(PyObject.java:653)
at org.python.core.PyObject.__getitem__(PyObject.java:717)
at org.python.pycode._pyx21494.f$0(:36)
at org.python.pycode._pyx21494.call_function()
at org.python.core.PyTableCode.call(PyTableCode.java:173)
at org.python.core.PyCode.call(PyCode.java:18)
at org.python.core.Py.runCode(Py.java:1687)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:796)
at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.runCode(ProjectScriptLifecycle.java:819)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:748)
at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.runCode(ProjectScriptLifecycle.java:800)
at com.inductiveautomation.ignition.common.script.TagChangeScriptExecutor$TagChangeExecutionCallback.execute(TagChangeScriptExecutor.java:242)
at com.inductiveautomation.ignition.common.script.TagChangeScriptExecutor$TagChangeExecutionCallback.execute(TagChangeScriptExecutor.java:194)
at com.inductiveautomation.ignition.common.util.SerialExecutionQueue$PollAndExecute.run(SerialExecutionQueue.java:102)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: org.python.core.PyException: TypeError: 'generator' object is unsubscriptable
Assuming that it is exactly the same script, I'm guessing that you need to change:
params["Dest"] = values[7]
to
params["Dest"] = dest
Probably need to do it in both places you have the script, I suspect that the first one worked because it took the "Bag"
dest_type route.
Exactly this.
Here, values is a generator. It doesn't hold any values, it generates them.
When you do a, b, c = (generator expression)
, it generates the values so that it can assign them to your variables.
This is why you can't subscript value
here. list(values)[7]
would work, as list
would 'tell' the generator to make values, so that list
can use them to create a list, but it's pointless since you already have the value in the variable dest
.
@lrose @pascal.fragnoud Yes, that was it.
Successfully logged data from all three machines. After about 4 logs per machine I just started to receive the following error in my logs. Not sure if this is new thread worthy? saw a similar thread but I did not see a solution there.
java.util.concurrent.TimeoutException: senderContext=567279 timed out waiting 2000ms for response
at com.digitalpetri.enip.EtherNetIpClient.lambda$writeCommand$5(EtherNetIpClient.java:173)
at io.netty.util.HashedWheelTimer$HashedWheelTimeout.run(HashedWheelTimer.java:715)
at io.netty.util.concurrent.ImmediateExecutor.execute(ImmediateExecutor.java:34)
at io.netty.util.HashedWheelTimer$HashedWheelTimeout.expire(HashedWheelTimer.java:703)
at io.netty.util.HashedWheelTimer$HashedWheelBucket.expireTimeouts(HashedWheelTimer.java:790)
at io.netty.util.HashedWheelTimer$Worker.run(HashedWheelTimer.java:503)
"Error brownsing Symbols in Controller:Global"
That is a different issue, most likely unrelated to what you were doing here.