Hello everyone. I'm facing a weird issue with a script that gives me error only the first time I try to execute it, then it doesn't work also but doesn't show the error again!
The error is:
([edge]Test/MoveToPanelHome/Trigger, valueChanged) Error executing tag event script: Traceback (most recent call last): File "<tagevent:valueChanged>", line 11, in valueChanged File "<module:OPCMethods>", line 63, in callMethod File "<module:OPCMethods>", line 63, in callMethod at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.lambda$operateOnPage$0(AbstractScriptingFunctions.java:64) at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.operateOnSession(AbstractScriptingFunctions.java:120) at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.operateOnPage(AbstractScriptingFunctions.java:47) at com.inductiveautomation.perspective.gateway.script.PerspectiveScriptingFunctions.popupAction(PerspectiveScriptingFunctions.java:758) at com.inductiveautomation.perspective.gateway.script.PerspectiveScriptingFunctions.openPopup(PerspectiveScriptingFunctions.java:240) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.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.IllegalArgumentException: java.lang.IllegalArgumentException: No perspective page attached to this thread.
I'm calling a script from project library on a tag value changed, and change the trigger tag using a button in perspective. The scripts are the following sequentially:
First script on the button
def runAction(self, event):
system.tag.configure("[edge]Test/GetCentroid", [{"name" : "Trigger", "sessionId" : str(self.session.props.id)}], "m")
system.tag.writeBlocking(["[edge]AB_Test/EP_Job_GetCentroid/Trigger"], [True])
Second script on the tag value changed
def valueChanged(tag, tagPath, previousValue, currentValue, initialChange, missedEvents):
if (not initialChange) and (currentValue.value == True) and (currentValue.value != previousValue.value) and (currentValue.quality.good) and (previousValue.quality.good):
# Parsing Method path in AB and EP
pathEP = '/'.join(tagPath.split("/")[:-1])
pathAB = tag['parameters']['ABPath']
# Parsing sessionId
sessionId = tag['sessionId']
# Call the Method
OPCMethods.callMethod(pathEP, pathAB, sessionId)
Third script in project library
def callMethod(pathEP, pathAB, thisSession):
logger = system.util.getLogger("DiagMethod")
logger.info(thisSession)
# Reading OPC method params (OPC Connection Name, OPC Server Namespace, ObjectID, MethodID)
opc = system.tag.readBlocking(["[edge]EastmanPro/OPCConnection", "[edge]EastmanPro/Namespace", pathEP + "/ObjectId", pathEP + "/MethodId"])
conn, ns = opc[0].value, opc[1].value
objectId, methodId = ns + opc[2].value, ns + opc[3].value
# Init args and outputs
args = []
outs = []
# Browse AB UDT to get args and outs
try:
udtAB = system.tag.browse(pathAB)
except Exception as e1:
logger.warning("Error1" + str(e1))
try:
system.perspective.openPopup("pathABError1", "Popups/ErrorBox", params = {"message" : "Error 1: Invalid AB Path.\n 'ABPath' parameter that refers to method UDT in AB PLC is invalid."}, title = "Error", sessionId = thisSession)
except Exception as e1hf:
logger.error("Error1HF" + str(e1hf))
return
# Read args values and outs names/number
for tag in udtAB:
if "Arg" in tag["name"]:
args.append(system.tag.readBlocking(pathAB + "/" + tag["name"])[0].value)
if "Return" in tag["name"]: #tag["name"] == "Return1" or tag["name"] == "Return2":
outs.append(str(tag["fullPath"]))
# Sort args and outs
args = sorted(args)
outs = sorted(outs)
# Call the method
try:
method = system.opcua.callMethod(conn, objectId, methodId, args)
except Exception as e2:
logger.info(" ".join(list((str(conn), str(objectId), str(methodId), str(args)))))
logger.error("Error2: " + str(e2))
try:
system.perspective.openPopup("methodCallError2", "Popups/ErrorBox", params = {"message" : "Error 2: Method call failed.\nOne of the following parameters is invalid:\n - Ignition OPC client connection name.\n - EastmanPro OPC server Namespace.\n - ObjectId (NodeId of the Object Node the Method is a member of).\n - MethodId.\n - List of Inputs (check data types and order)."}, title = "Error", sessionId = thisSession)
except Exception as e2hf:
logger.error("Error2HF: " + str(e2hf))
# Write StatusCodes return for Call and inputs
statPaths = [pathEP + "/StatusCode_Call", pathEP + "/StatusCode_Inputs"]
statCall = [str(method[0][0]), method[0][1], method[0][2]]
statInputs = system.dataset.toDataSet(["Code", "Name", "Description"], [list(i) for i in method[1]])
system.tag.writeBlocking(statPaths, [statCall, statInputs])
# Write back to the Return (Assuming method return status as a 1st value eg. [Return, Return1. Return2])
try:
system.tag.writeBlocking(outs, method[2])
except Exception as e3:
logger.error("Error3: " + str(e3) + " Paths: " + str(outs) + " Returns: " + str(method[2]))
# Prompt the success message and Trigger tag reset option
try:
system.perspective.openPopup("methodCallSuccess", "Popups/DoneBox", params = {"message" : "Method has been called successfully!\nDo you need to reset AB Trigger tag?", "pathAB" : pathAB} if method[0][0] == 0 else {"message" : "Method call failed!\nDo you need to reset AB Trigger tag?", "pathAB" : pathAB}, title = "Done", sessionId = thisSession)
except Exception as df:
logger.error("DoneFail" + str(df))
Now I have three questions:
- Why do I still get this error (No perspective page attached to this thread.No perspective page attached to this thread.), although I'm passing the sessionId correctly?
- Why does the error appear in the logs only the first execution, then never appear until I restart Ignition service?
- Why don't (try, except) handle the error (first execution or even after that)?
Thanks and sorry for the long question