Client Event Startup Script invokeLater

Hi All,

I have a project that auto logs into a guest account and a custom login window (Vision) that opens on startup.

For reasons I don't want to bore anyone with, I then have the following client event startup script:

user = system.security.getUsername()
if user == 'Guest':
	tagPaths = ["[System]Client/Network/Hostname"]
	tag = system.tag.readBlocking(tagPaths)
	if tag[0].value == 'MyPC':
		success = system.security.switchUser('username', 'password')
		if success:
			windowPath = 'User Management/Switch User'
			def closeWindow(windowPath):
				import system
				system.nav.closeWindow(windowPath)
			system.util.invokeLater(closeWindow(windowPath), 1000)

I am trying my hardest not to use sleep (as @pturmel strongly recommended on multiple forum posts) but I am getting this error and the window does not close:

TypeError: 'NoneType' object is not callable

	at org.python.core.Py.TypeError(Py.java:236)
	at org.python.core.PyObject.__call__(PyObject.java:396)
	at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:843)
	at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:825)
	at com.inductiveautomation.factorypmi.application.script.builtin.ClientSystemUtilities.lambda$invokeLater$0(ClientSystemUtilities.java:273)
	at java.desktop/java.awt.event.InvocationEvent.dispatch(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)

Ignition v8.1.21 (b2022092908)
Java: Azul Systems, Inc. 11.0.15

Further info:

I only started trying to close the window after a delay after it seemed the last line of the previous version on my script was not doing anything:

user = system.security.getUsername()
if user == 'Guest':
	tagPaths = ["[System]Client/Network/Hostname"]
	tag = system.tag.readBlocking(tagPaths)
	if tag[0].value == 'MyPC':
		success = system.security.switchUser('username', 'password')
		if success:
			windowPath = 'User Management/Switch User'
			system.nav.closeWindow(windowPath)

And I added the import system to the defined function because I was getting this error without it:

Traceback (most recent call last):
File "", line 15, in
File "", line 14, in closeWindow
NameError: global name 'system' is not defined

at org.python.core.Py.NameError(Py.java:261)
at org.python.core.PyFrame.getglobal(PyFrame.java:265)
at org.python.pycode._pyx2.closeWindow$1(:14)
at org.python.pycode._pyx2.call_function()
at org.python.core.PyTableCode.call(PyTableCode.java:173)
at org.python.core.PyBaseCode.call(PyBaseCode.java:134)
at org.python.core.PyFunction.call(PyFunction.java:416)
at org.python.pycode._pyx2.f$0(:16)
at org.python.pycode._pyx2.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:800)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:769)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:736)
at com.inductiveautomation.factorypmi.application.FPMIApp.startup(FPMIApp.java:486)
at com.inductiveautomation.factorypmi.application.runtime.ClientPanel.lambda$startupApp$8(ClientPanel.java:881)
at java.desktop/java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)

Ignition v8.1.21 (b2022092908)
Java: Azul Systems, Inc. 11.0.15

and I found a forum thread that told me to import system.

"NoneType object is not callable" - you're calling closeWindow(), which has no return statement (and thus returns None) - which is then passed into system.util.invokeLater and throws the error.

invokeLater expects the first argument to be a callable reference, and it will be invoked with no arguments. So you need to capture any arguments you want to pass in. An easy way to do this (there are lots) is to use a default argument:

def closeWindow(windowPath=windowPath):
	import system
	system.nav.closeWindow(windowPath)
system.util.invokeLater(closeWindow, 1000)
2 Likes

Thanks for the explanation and solution, I was also able to get away with no delay value for the invokeLater call which I am further happy about :smiley:.