Script works on button/window, but fails in Client Timer

I’m receiving a weird error when running code in a Client Timer script. The same code works fine in either a button clicked or window opened event, but inside the timer it fails.

The code snippet:

import os, sys, time, datetime from stat import S_ISREG,ST_CTIME,ST_MODE,ST_SIZE dirpath="G:\\Shared\\Incident Review" filelist=(os.path.join(dirpath,fn) for fn in os.listdir(dirpath)) filelist=((os.stat(path),path,os.stat(path)) for path in filelist) filelist=((stat[ST_CTIME],path,stat[ST_SIZE]) for stat,path,stat in filelist if S_ISREG(stat[ST_MODE]))

The snippet above is part of a larger script that is checking a network directory for the existence of a file. The above is getting the files in that directory along with file size and creation date.

The code works without issue on a button click event, or on a window open event.

I wanted to put this in a client timer to check automatically, but when I do, I get the following error message in the log file (“global name ‘os’ is not defined”):

ERROR [TimerScriptTask-SharedScriptTimer[IMMI_OPX_Dashboard_V2]] Error executing global timer script: IMMI_OPX_Dashboard_V2/GlobalRI_Check @5,000ms . Repeat errors of this type will be logged as ‘debug’ messages.
Traceback (most recent call last):
File “<TimerScript:IMMI_OPX_Dashboard_V2/GlobalRI_Check @5,000ms >”, line 23, in
File “<TimerScript:IMMI_OPX_Dashboard_V2/GlobalRI_Check @5,000ms >”, line 18, in
File “<TimerScript:IMMI_OPX_Dashboard_V2/GlobalRI_Check @5,000ms >”, line 17, in
File “<TimerScript:IMMI_OPX_Dashboard_V2/GlobalRI_Check @5,000ms >”, line 16, in
NameError: global name ‘os’ is not defined

at org.python.core.Py.NameError(Py.java:260)
at org.python.core.PyFrame.getglobal(PyFrame.java:265)
at org.python.pycode._pyx5.f$1(<TimerScript:IMMI_OPX_Dashboard_V2/GlobalRI_Check @5,000ms >:16)
at org.python.pycode._pyx5.call_function(<TimerScript:IMMI_OPX_Dashboard_V2/GlobalRI_Check @5,000ms >)
at org.python.core.PyTableCode.call(PyTableCode.java:165)
at org.python.core.PyGenerator.__iternext__(PyGenerator.java:149)
at org.python.core.PyGenerator.__iternext__(PyGenerator.java:131)
at org.python.pycode._pyx5.f$2(<TimerScript:IMMI_OPX_Dashboard_V2/GlobalRI_Check @5,000ms >:17)
at org.python.pycode._pyx5.call_function(<TimerScript:IMMI_OPX_Dashboard_V2/GlobalRI_Check @5,000ms >)
at org.python.core.PyTableCode.call(PyTableCode.java:165)
at org.python.core.PyGenerator.__iternext__(PyGenerator.java:149)
at org.python.core.PyGenerator.__iternext__(PyGenerator.java:131)
at org.python.pycode._pyx5.f$3(<TimerScript:IMMI_OPX_Dashboard_V2/GlobalRI_Check @5,000ms >:18)
at org.python.pycode._pyx5.call_function(<TimerScript:IMMI_OPX_Dashboard_V2/GlobalRI_Check @5,000ms >)
at org.python.core.PyTableCode.call(PyTableCode.java:165)
at org.python.core.PyGenerator.__iternext__(PyGenerator.java:149)
at org.python.core.PyGenerator.__iternext__(PyGenerator.java:131)
at org.python.core.WrappedIterIterator.hasNext(WrappedIterIterator.java:23)
at org.python.core.PyList.<init>(PyList.java:73)
at org.python.core.SortedFunction.__call__(__builtin__.java:1245)
at org.python.core.PyObject.__call__(PyObject.java:320)
at org.python.pycode._pyx5.f$0(<TimerScript:IMMI_OPX_Dashboard_V2/GlobalRI_Check @5,000ms >:32)
at org.python.pycode._pyx5.call_function(<TimerScript:IMMI_OPX_Dashboard_V2/GlobalRI_Check @5,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:623)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:582)
at com.inductiveautomation.ignition.common.script.TimerScriptTask.run(TimerScriptTask.java:99)
at java.util.TimerThread.mainLoop(Unknown Source)
at java.util.TimerThread.run(Unknown Source)

Basically, the code is failing anywhere I attempt to use the os library, like “os.listdir(dirpath)”, etc.

I also could put this into a Gateway Timer script, but I need to setup the .conf file to use the Java Service Wrapper to define a network drive. That requires a gateway restart, so I’m delaying that option as this issue is on a production instance with 50+ clients.

My fallback could be to use a timer on the window that does a button.doClick() to execute the code, but I thought I would post here to see if anyone can see if I’m doing something simple/stupid/wrong that would cause this issue. I submitted a help ticket, but so far support says that I should have no issue importing a library in a Client Script, and is not sure why the error is occurring.

Ignition 7.8.3
Java 1.8.0_91

Any info is appreciated. Thanks.

Hi Steve,

As a test can you create a new Client Timer Script and have as its only code “import os”. And if that works then add a single os function call? Try to find the simplest case where it doesn’t work. That might help you understand what is wrong.

Best,