Hi All,
I just wanted to update with the final code I used as my solution, in case it can help anyone. I implemented multiple watchers, modified polling to use WatchService.take for immediate notification of changes, and created Gateway Tag Change scripts to govern each watcher’s start and stop. This way they can be manipulated from clients if necessary by using:
system.tag.write('endWatchA', 1)
system.tag.write('startWatchA', 1)
The Gateway Shutdown script was necessary to prevent multiple watcher threads opening when Saving and Publishing changes from the Designer.
As a final note, the try/except block in the watch method should catch a ClosedWatchServiceException but I could not get Ignition to recognize this exception. I tried importing java.lang.Exception, and java.nio.file.ClosedWatchServiceException
Gateway Startup Event Script
project.watcher
####Project Script ‘Watcher’
from java.nio.file import FileSystems,Files
from java.io import File
from java.nio.file import StandardWatchEventKinds as swek
import system
system.util.getGlobals()['GWLog'] = system.util.getLogger("GatewayStartupEventLog")
class fileWatcher():
def __init__(self, folderPath, type):
self.folderPath = folderPath
self.type = type
self._run = False
self.watcher = None
system.util.getGlobals()['GWLog'].info('INIT %s' %self.type)
self.run()
def watch(self):
self.watcher = FileSystems.getDefault().newWatchService()
p = File(self.folderPath).toPath()
key = p.register(self.watcher, swek.ENTRY_CREATE)
kill = False
while self._run:
try:
k = self.watcher.take()
except:
kill = True
if not kill:
for e in k.pollEvents():
if e.kind() == swek.OVERFLOW:
pass
if e.kind() == swek.ENTRY_CREATE:
#Do something with self.type & file path str(p.resolve(e.context()))
k.reset()
system.util.getGlobals()['GWLog'].info('END %s' %self.type)
def run(self):
system.util.getGlobals()['GWLog'].info('START %s' %self.type)
if not self._run:
system.util.getGlobals()['GWLog'].info('RUN %s' %self.type)
self._run = True
system.util.invokeAsynchronous(self.watch)
def kill(self):
system.util.getGlobals()['GWLog'].info('KILL %s' %self.type)
self._run = False
self.watcher.close()
system.util.getGlobals()['aWatch'] = fileWatcher('C:/Users/pathA', 1)
system.util.getGlobals()['bWatch'] = fileWatcher('C:/Users/pathB', 2)
system.util.getGlobals()['cWatch'] = fileWatcher('C:/Users/pathC', 3)
####Gateway Tag Change Script ‘endWatchA’ w/ Memory Tag ‘endWatchA’ as BOOLEAN
Repeat as necessary for endWatchB, endWatchC, etc.
if currentValue.value:
system.util.getGlobals()['aWatch'].kill()
system.tag.write('endWatchA', 0)
####Gateway Tag Change Script ‘startWatchA’ w/ Memory Tag ‘startWatchA’ as BOOLEAN
Repeat as necessary for startWatchB, startWatchC, etc.
if currentValue.value:
system.util.getGlobals()['aWatch'].run()
system.tag.write('startWatchA', 0)
####Gateway Shutdown Event Script
system.util.getGlobals()['aWatch'].kill()
system.util.getGlobals()['bWatch'].kill()
system.util.getGlobals()['cWatch'].kill()