Client Timer Script for Rotating between different windows

7.9.5
I am looking to write a Client Timer script to be able to swap between a list of windows. This is what I have so far.

swapWindows = {"Melt Overview":"Test","Test 2":"Test 3","Test 3":"Test 5"}
win = system.nav.getCurrentWindow()
nextWindow = swapWindows[win]
system.nav.swapTo(nextWindow)

When I run the script I get a error:

07:58:48.068 [designer-script-shared-timer-[Melt_Dashboard]] ERROR com.inductiveautomation.ignition.common.script.TimerScriptTask - Error executing global timer script: Melt_Dashboard/windowRotate @30,000ms . Repeat errors of this type will be logged as ‘debug’ messages.
com.inductiveautomation.ignition.common.script.JythonExecException: Traceback (most recent call last):
File “<TimerScript:Melt_Dashboard/windowRotate @30,000ms >”, line 3, in
KeyError

at org.python.core.Py.KeyError(Py.java:225)
at org.python.core.PyObject.__getitem__(PyObject.java:655)
at org.python.pycode._pyx26.f$0(<TimerScript:Melt_Dashboard/windowRotate @30,000ms >:4)
at org.python.pycode._pyx26.call_function(<TimerScript:Melt_Dashboard/windowRotate @30,000ms >)
at org.python.core.PyTableCode.call(PyTableCode.java:165)
at org.python.core.PyCode.call(PyCode.java:18)
at org.python.core.Py.runCode(Py.java:1275)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:634)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:601)
at com.inductiveautomation.ignition.common.script.TimerScriptTask.run(TimerScriptTask.java:88)
at java.util.TimerThread.mainLoop(Unknown Source)
at java.util.TimerThread.run(Unknown Source)

Caused by: org.python.core.PyException: Traceback (most recent call last):
File “<TimerScript:Melt_Dashboard/windowRotate @30,000ms >”, line 3, in
KeyError

... 12 common frames omitted

That means the result from system.nav.getCurrentWindow() wasn’t one of the windows in your dictionary (as a key). You have to handle that case. Either test with if win in swapWindows: or use a try-except block to catch the exception.

I tried the if win example not for sure on the try-except one. I get a error with the if win example.

if win in swapWindows:
	swapWindows = {"Melt Overview":"Test","Test 2":"Test 3","Test 3":"Test 5"}
	win = system.nav.getCurrentWindow()
	nextWindow = swapWindows[win]
	system.nav.swapTo(nextWindow)

09:28:02.592 [designer-script-shared-timer-[Melt_Dashboard]] ERROR com.inductiveautomation.ignition.common.script.TimerScriptTask - Error executing global timer script: Melt_Dashboard/windowRotate @30,000ms . Repeat errors of this type will be logged as ‘debug’ messages.
com.inductiveautomation.ignition.common.script.JythonExecException: Traceback (most recent call last):
File “<TimerScript:Melt_Dashboard/windowRotate @30,000ms >”, line 1, in
NameError: name ‘win’ is not defined

at org.python.core.Py.NameError(Py.java:260)
at org.python.core.PyFrame.getname(PyFrame.java:257)
at org.python.pycode._pyx73.f$0(<TimerScript:Melt_Dashboard/windowRotate @30,000ms >:5)
at org.python.pycode._pyx73.call_function(<TimerScript:Melt_Dashboard/windowRotate @30,000ms >)
at org.python.core.PyTableCode.call(PyTableCode.java:165)
at org.python.core.PyCode.call(PyCode.java:18)
at org.python.core.Py.runCode(Py.java:1275)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:634)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:601)
at com.inductiveautomation.ignition.common.script.TimerScriptTask.run(TimerScriptTask.java:88)
at java.util.TimerThread.mainLoop(Unknown Source)
at java.util.TimerThread.run(Unknown Source)

Caused by: org.python.core.PyException: Traceback (most recent call last):
File “<TimerScript:Melt_Dashboard/windowRotate @30,000ms >”, line 1, in
NameError: name ‘win’ is not defined

... 12 common frames omitted

win needs to be defined before you can do any testing with it. Try this:

swapWindows = {"Melt Overview":"Test","Test 2":"Test 3","Test 3":"Test 5"}
win = system.nav.getCurrentWindow()
if win in swapWindows.keys():
	nextWindow = swapWindows[win]
	system.nav.swapTo(nextWindow)
1 Like

I wouldn’t expect you to be able to test win before you’ve assigned a value to it.

in the client it switched to the second window but then it stopped

Your second window is “Test”, but you have no key named “Test” to say what should follow.

Probably because your dictionary doesn’t include some of the windows you’re swapping to, as keys. For example the first key in your dict has a value of “test”. There is no key called “test” and so when the script changes the window to this and the script runs again, it’s not going to find it in the dictionary and will therefore not result in any more window changes. Your issue is semantic

Phil, beat me to it :sweat_smile:

1 Like

Consider using a list of window names instead of a dictionary. Use the .index() method of the list to find the current window, then use (idx+1) % len(thelist) to pick the next window. Then there’s no need to explictly make keys and values for every transition.

2 Likes

Watch out for that Jordan dude–he’ll steal your comment glory if I don’t… :star_struck:

2 Likes

Along the same vein of questioning.

how can you accomplish this with out using a tag

If you want to use Phil’s suggestion on using a list, it would look something like this:

swapWindows =[
              "Melt Overview",
              "Test",
			  "Test 2",
			  "Test 3",
			  "Test 5"
			 ]

win = system.nav.getCurrentWindow()

if win in swapWindows:
	idx = swapWindows.index(win)
	nextIdx = (idx + 1) % len(swapWindows)
	system.nav.swapTo(swapWindows[nextIdx])

Note that you can put a list (or dictionary, for that matter) on separate lines to make it easier to read, and make sure the order of items is… um… in order.

3 Likes

Thanks for the update. I was able to get it working like this. Notice I did change the screen names prior to finishing the script.

swapWindows = {"Casting Overview": "Furnace Overview" , "Furnace Overview" :"Casting Overview"}
win = system.nav.getCurrentWindow()

if win in swapWindows.keys():
	nextWindow = swapWindows[win]
	system.nav.swapTo(nextWindow)

You’re still creating more work for yourself and for others by using a dictionary instead of a list

2 Likes

I took your advice and changed it to JordanCClark’s example of a list.

3 Likes